文件描述符

I/O重定向和管道——《Unix/Linux编程实践教程》读书笔记(第10章)

拈花ヽ惹草 提交于 2019-12-07 16:23:53
1、I/O重定向的概念与原因 及 标准输入、输出的标准错误的定义 所以的Unix I/O重定向都基于标准数据流的原理。三个数据了分别如下: 1)标准输入——需要处理的数据流 2)标准输出——结果数据流 3)标准错误输出——错误消息流 概念:所以的Unix工具都使用文件描述符0、1和2。标准输入文件的描述符是0,标准输出的文件描述符是1,而标准错误输出的文件描述符则是2。Unix假设文件描述符0、1、2已经被打开,可以分别进行读写操作。 通常通过shell命令行运行Unix系统工具时,stdin、stdout、stderr连接在终端上。因此,工具从键盘读取数据并且把输出和错误消息写到屏幕。 大部分的Unix工具处理从文件或标准输入读入的数据。如果在命令行上给出了文件名,工具将从文件读取数据。若无文件名,程序则从标准输入读取数据。从另一方面说,大多数程序并不接收输出文件名;它们总是将结果写到文件描述符1,并将错误消息写到文件描述符2。如果希望将进程的输出写道文件或另一个进程的输入去,就必须重定向相应的文件描述符。 重定向I/O的是shell而不是程序 最低可用文件描述符(lowest-available-fd)原则:文件描述符是一个数组的索引号。每个进程都有其打开的一组文件。这些打开的文件被保持在一个数组中。文件描述符即为某文件在此数组中的索引。当打开文件时

转载-C语言FILE类型与标准I/O流

自闭症网瘾萝莉.ら 提交于 2019-12-07 02:55:07
权威资料 <cstdio> (stdio.h) - C++ Reference http://www.cplusplus.com/reference/cstdio/ 先来了解下什么是标准IO以及文件IO。 标准IO以及文件IO。 标准IO:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很多细节。例如缓存分配,以优化长度执行IO等。标准的IO提供了三种类型的缓存。 (1)全缓存:当填满标准IO缓存后才进行实际的IO操作。 (2)行缓存:当输入或输出中遇到新行符时,标准IO库执行IO操作。 (3)不带缓存:stderr就是了。 文件IO:文件IO称之为 不带缓存的IO (unbuffered I/O)。不带缓存指的是每个read,write都调用内核中的一个系统调用。也就是一般所说的 低级I/O —— 操作系统提供的基本IO服务 ,与os绑定,特定于linix或unix平台。 2区别 首先:两者一个显著的不同点在于, 标准I/O默认采用了缓冲机制 ,比如调用fopen函数, 不仅打开一个文件,而且建立了一个缓冲区 (读写模式下将建立两个缓冲区),还创建了一个 包含文件和缓冲区相关数据的数据结构 。 低级I/O一般没有采用缓冲,需要自己创建缓冲区, 不过其实在linix或unix系统中

如何优雅地将printf的打印保存在文件中?

旧城冷巷雨未停 提交于 2019-12-06 22:10:40
我们都知道,一般使用printf的打印都会直接打印在终端,如果想要保存在文件里呢?我想你可能想到的是重定向。例如: $ program > result.txt 这样printf的输出就存储在result.txt中了。 当然了,如果你既想打印在终端,又想保存在文件,还可以使用tee命令: program | tee result.txt 注:program为你运行的程序。 不过文本介绍了不是通过命令行的方式,而是通过代码实现。 写文件 你可能会想,那不用printf,直接将打印写入到文件不就可以了?类似于下面这样: #include<stdio.h> int main(void) { FILE *fp = fopen("log.txt","w+"); if(NULL == fp) { printf("open failed "); return -1; } int a = 10; fprintf(fp,"test content %d ",a); fclose(fp); return 0; } 不过这需要将原先的printf改用fprintf,修改了最原始的代码。但是本文并不是说明如何实现一个logging功能,而是如何将printf的原始打印保存在文件中。 重定向 实际上,我们的程序在运行起来后,都会有三个文件描述符: 0 标准输入 1 标准输出 2 标准错误

进程间通信 IPC interprocess communication

非 Y 不嫁゛ 提交于 2019-12-06 20:09:55
1,管道,FIFO 2, 信号 3,消息队列 4,共享类存 5.文件映射 6.socket ( 1 )管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。   ( 2 )命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。   ( 3 )信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。   ( 4 )消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺   ( 5 )共享内存:使得多个进程可以访问同一块内存空间

node.js多进程架构

倖福魔咒の 提交于 2019-12-06 18:59:27
node.js是单进程应用,要充分利用多核cpu的性能,就需要用到多进程架构。 作为web服务器,不能多个进程创建不同的socket文件描述符去accept网络请求, 有经验的同学知道,如果端口被占用了,再跑一个监听该端口的服务就会报EADDRINUSE异常。那么问题来了,多进程架构如何去解决这个问题? 我们把多进程架构设计成典型的master-workers架构, 一个master, 多个worker。 master-workers架构如下图所示: 我们可以在master进程代理accept请求然后分配给worker处理。但客户端进程连接到master进程,master进程连接到worker进程需要用掉两个文件描述符,会浪费掉一倍数量的文件描述符。 所以交由worker来accept请求会是更好的方案。 master先创建一个server监听端口,然后通过进程间通信,把socket文件描述符传递给所有的worker进程, worker进程用传递过来的socket文件描述符封装成server(感官上好像是把一个server对象发送给另一个进程,其实是把相应的句柄封装后,通过JSON.stringify()序列化再发送, 接收端进程还原成相应的句柄。) 然后,还有一个问题,假如其中一个worker进程异常退出了怎么办, 这个时候,worker进程应该要通知到master进程

(二十九)python3 之os模块

两盒软妹~` 提交于 2019-12-06 14:17:11
在自动化测试中,经常需要查找操作文件,比如说查找配置文件(从而读取配置文件的信息),查找测试报告(从而发送测试报告邮件),经常要对大量文件和大量路径进行操作,这就依赖于os模块,所以今天整理下比较常用的几个方法。网上这方面资料也很多,每次整理,只是对自己所学的知识进行梳理,从而加深对某个模块的使用。 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.curdir 返回当前目录: ('.') os.pardir 获取当前目录的父目录字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename(

我对网络IO的理解

回眸只為那壹抹淺笑 提交于 2019-12-06 13:47:17
Unix/Linux系统下IO主要分为磁盘IO,网络IO,我今天主要说一下对网络IO的理解,网络IO主要是socket套接字的读(read)、写(write),socket在Linux系统被抽象为流(stream)。 网络IO模型 在Unix/Linux系统下,IO分为两个不同阶段: 等待数据准备好 从内核向进程复制数据 阻塞式I/O 阻塞式I/O(blocking I/O)是最简单的一种,默认情况下,socket 套接字的系统调用都是阻塞的,我以recv/recvfrom 理解一下网络IO的模型。当应用层的系统调用recv/recvfrom时,开启Linux的系统调用,开始准备数据,然后将数据从内核态复制到用户态,然后通知应用程序获取数据,整个过程都是阻塞的。两个阶段都会被阻塞。 阻塞I/O模型 图片来源于《Unix网络编程卷1》 阻塞I/O下开发的后台服务,一般都是通过多进程或者线程取出来请求,但是开辟进程或者线程是非常消耗系统资源的,当大量请求时,因为需要开辟更多的进程或者线程有可能将系统资源耗尽,因此这种模式不适合高并发的系统。 非阻塞式I/O 非阻塞IO(non-blocking I/O)在调用后,内核马上返回给进程,如果数据没有准备好,就返回一个error ,进程可以先去干其他事情,一会再次调用,直到数据准备好为止,循环往返的系统调用的过程称为轮询(pool)

Linux 下利用 Lsof 恢复误删文件

别等时光非礼了梦想. 提交于 2019-12-06 13:44:25
原理:在Linux系统的/proc 分区下保存着进程的目录和名字,包含fd(文件描述符)和其下的子目录(进程打开文件的链接),那么如果删除了一个文件,还存在一个 inode的引用:/proc/进程号/fd/文件描述符。我们只要知道当前打开文件的进程pid和文件描述符fd就能利用lsof工具列出进程打开的文件。 一、将 ls 的手册过滤掉主要控制符后重定向到文件ls.txt 中,并用more查看,CTRL + Z 暂停查看操作 1: [root@localhost script]# man ls |col -b > ls.txt 2: [root@localhost script]# more ls.txt 3: LS(1) User Commands LS(1) 4: 1: [1]+ Stopped more ls.txt 2: [root@localhost script]# 3: [root@localhost script]# jobs 4: [1]+ Stopped more ls.txt 5: 二、假设误删文件 ls.txt 1: [root@localhost script]# rm ls.txt 2: rm:是否删除 一般文件 “ls.txt”? y 三、利用lsof找到进程6511、并拷贝恢复,只能在这个文件被使用或调用的情况下有效 3: [root

python之文件处理

对着背影说爱祢 提交于 2019-12-06 06:54:05
一.基础操作 1.打开文件 f = open(文件路径,打开方式,编码模式) #打开文件并返回操作对象 打开方式 说明 注意 'r' 只读方式 文件必须存在 'w' 只写方式 文件不存在则创建文件 文件存在则清空文件 'a' 追加方式 文件不存在创建文件 'r+'/'w+' 读写方式 'a+' 追加和读写方式 2.读取文件 f.read() #不加参数默认读取整个文件 例如:read(1024) #读取1024个字节 f.readline() #不加参数默认读取一行 f.readlines()#读取buffer字节大小的内容 ,返回每一行所组成的列表 iter #使用迭代器读取文件,读取所有内容 例子:   iter_f = iter(f)   lines = 0   for line in iter_f :     f.read(line) #一行行读取     lines += 1   return lines #一共多少行 3.文件写入与写缓存 f.write(str) #将字符串写入文件 f.writelines(sequences_of_strings) #写多行到文件,参数为可迭代对象 注意: 写之后,直接查看文件,会发现内容并没有被写到文件里,因为此时内容还在缓存中,并没有写到磁盘上 解决方法: (1)主动调用close()或者flush方法,写缓存同步到磁盘;(2

文件描述符fd,struct files_struct

安稳与你 提交于 2019-12-06 04:16:37
程序可以理解为硬盘上的普通二进制文件;进程是加载到内存中的二进制文件,除了加载到内存中的二进制文件外,还附有所有对于该二进制文件 描述信息的结构体 ,描述该进程的结构体叫 PCB(进程控制块) ,在这就不在讨论。对于程序与进程,也就可以简单地理解为是否有PCB(进程控制块)。下面我们再来讨论PCB与file_struct的关系。 在每一个PCB中,都有一个文件描述符表,通过文件描述符索引指向file_struct(系统打开文件表) 。 文件描述符在形式上是一个非负整数,实际上, 它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表 ,当程序打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。也就是说,一个程序能够访问文件是因为给这个程序分配了文件描述符。 下面我们来讨论file_struct里面具体有哪些内容, file结构体定义在linux系统中的(/kernels/include/linus/fs.h)文件中。 file_struct结构如下 struct file {   union {   struct list_head fu_list; //文件对象链表指针linux/include/linux/list.h   struct rcu_head fu_rcuhead; //RCU(Read-Copy Update)是Linux 2