文件描述符

Linux IO模型漫谈(1)

南楼画角 提交于 2020-04-06 04:09:19
基础知识 Linux将所有外部设备都看做一个文件来进行操作。因此,linux对所有外部设备的操作都可以看做是文件的操作。文件的操作当然需要有个标示描述它,这就是文件描述符(file descriptor)。 linux的IO操作如何形象理解呢? 我们说网络socket的read()是一个IO操作命令,具体流程是这样的: 应用程序调用read命令,通知内核需要做读取数据操作 内核创建一个文件描述符 内核从物理层收到读数据的命令,从网络中获取数据包 数据包传递到TCP/IP层,解析数据包的头 内核将数据包缓存在文件描述符的读缓存区(接受缓存区)中,注意这里的读缓存区是在内核中的 当文件描述符读缓存区数据字节数大于应用程序定义的低水位的时候(read的一个参数),此时文件描述符处于读就绪的状态 将读缓存区中的数据复制到应用程序(用户区)返回 这里需要说明的是 1 每个文件描述符都有自己的读缓冲区和写缓冲区,读缓冲区对应的是read操作,写缓冲区对应的就是write操作了 2 读缓冲区和写缓冲区都是在内核区中 IO模型 现有的linux IO模型有5种: 阻塞式IO模型,非阻塞式IO模型,IO复用模型,信号驱动式IO模型,异步IO模型 经常弄不清楚的就是阻塞,非阻塞,异步,同步 说明一下 上图给出的同步异步标准是:数据描述符缓存是由谁来进行读取的?由用户程序读取,则判断为同步;由内核推送

unix环境高级编程——文件IO

南楼画角 提交于 2020-04-03 22:11:16
可用的文件IO函数:打开文件,读文件,写文件等(不带缓冲的IO函数(指每个read或write函数都调用内核的一个系统调用))    不是ISO C的组成部分,但是时POSIX和SUS的组成部分 UNIX系统中常用的文件IO函数:open,read,wirte,lseek,close函数 当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符(非负整数) UNIX的shell把文件描述符0与标准输入关联,文件描述符与标准输出关联,文件描述符2与标准错误输出关联,在POSIX标准中,对应的被替换为符号常量STDIN_FLLENO,SEDOUT_FLLENO,STDERR_FLLENO  <unistd,h> 函数open和openat (fcntl.h) int open(const char* path,int oflag,.../*mode_t mode*/); int openat(int fd,const char* path,int oflag,.../*mode_t mode*/); 将最后一个参数写为...,表明余下的参数的数量以及类型是可变的 由open和openat函数返回的文件描述符一定是最小的未用的描述符数值 若path参数指定为绝对路径,fd参数无用,openat函数相当于open函数    path指定的是相对路径

Python学习之-- IO 操作

浪尽此生 提交于 2020-04-03 04:09:46
阻塞IO / 非阻塞IO /IO多路复用 / 异步IO 说明:同步IO包含(阻塞IO / 非阻塞IO /IO多路复用),因为他们有个共同特性就是都需要内核态到用户态的一个等待。 基本概念解释,环境限定为linux: 1:用户空间和内存空间 首先操作系统是采用虚拟存储器,就32位系统来说,它的虚拟存储空间是2的32次方==4G,操作系统的核心是内核,它是独立于普通的应用程序,它可以访问受保护的内存空间,底层硬件等,为保障用户进程不能直接操作内核,操作系统将虚拟存储空间分为2部分,分为:内核空间和用户空间,内核空间将最高的1G字节(寻址:0xC0000000到0xFFFFFFFF)分配使用,最低的3G字节分配给用户空间,供进程使用。 2:进程切换 也就类似线程切换,由内核将正在CPU上执行的进程挂起,然后恢复以前挂起的进程,这就是进程切换。所以进程都是在操作系统的内核的支持下运行的。与内核紧密相连 从一个进程切换到另一个进程,运行过程如下: 1:保存处理机上下文,包括程序计数器和寄存器 2:更新PCB信息 3:把进程的PCB移入相应的队列, 4:选择另一个进程执行,并更新其PCB 5:更新内存管理的数据结构 6:恢复处理机上下文 3:进程的阻塞 当正在执行的进程运行期间,由于所期待的事情未发生,如(请求资源失败,某种操作的完成,新数据尚未到达等),则由系统自动执行阻塞原语

初步了解Unix系统的I/O模式

ε祈祈猫儿з 提交于 2020-03-29 13:37:12
I/O模式 对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。 当一个read操作发生时,它会经历两个阶段: 等待数据准备 将数据从内核拷贝到进程中 因为这两个阶段,Unix系统的IO分为五种模式: 阻塞 I/O(blocking IO) 非阻塞 I/O(nonblocking IO) I/O 多路复用( IO multiplexing) 信号驱动 I/O( signal driven IO) 异步 I/O(asynchronous IO) 阻塞 I/O 特点就是在IO执行的两个阶段,用户进程都被block了。 Linux中,默认情况下所有的socket都是blocking 非阻塞 I/O 特点是用户进程要不断得通过系统调用询问内核,文件描述的数据是否准备好了,这种方式称为轮询(polling)。 如果数据还没有准备好,用户进程不会被阻塞,而是立刻返回一个error。用户进程收到error可以再次进行read操作。 I/O 多路复用 特点是单个用户进程可以处理多个 I/O 事件,减少多进程切换带来的系统开销。 分成三种形式: select poll epoll select 或者 poll 可以监视多个文件描述符,期间会被阻塞,任何一个描述符的数据准备好后通知用户进程,进程调用 recvfrom

python 核心编程 第九章

廉价感情. 提交于 2020-03-25 05:42:52
文件的输入和输出 打开文件 使用open()或者file()这两个函数是等效的。 r 以读方式打开 rU 或 Ua 以读方式打开, 同时提供通用换行符支持 (PEP 278) w 以写方式打开 (必要时清空) a 以追加模式打开 (从 EOF 开始, 必要时创建新文件) r+ 以读写模式打开 w+ 以读写模式打开 (参见 w ) a+ 以读写模式打开 (参见 a ) rb 以二进制读模式打开 wb 以二进制写模式打开 (参见 w ) ab 以二进制追加模式打开 (参见 a ) rb+ 以二进制读写模式打开 (参见 r+ ) wb+ 以二进制读写模式打开 (参见 w+ ) ab+ 以二进制读写模式打开 (参见 a+ ) 文件的输入输出 read() 直接读取字节到字符串,读取到给定数目的字节 readline()读取文件的一行(包括行结束符),size参数默认为-1,代表读到行结束符。 readlines()读取所有剩余行,返回一个字符串列表,参数sizhint表示返回最大字节的大小。 truncate()它接受一个可选的 size 作为参数. 如果给定, 那么文 件将被截取到最多 size 字节处. 如果没有传递 size 参数, 那么默认将截取到文件的当前位置. 例如, 你刚打开了一个文件, 然后立即调用 truncate() 方法, 那么你的文件(内容)实际上被删除,

Linux网络IO模型

别来无恙 提交于 2020-03-24 13:53:25
同步和异步,阻塞和非阻塞 同步和异步 关注的是结果消息的通信机制 同步 : 同步的意思就是调用方需要主动等待结果的返回 异步 : 异步的意思就是不需要主动等待结果的返回,而是通过其他手段比如,状态通知,回调函数等。 阻塞和非阻塞 主要关注的是等待结果返回调用方的状态 阻塞 : 是指结果返回之前,当前线程被挂起,不做任何事 非阻塞 : 是指结果在返回之前,线程可以做一些其他事,不会被挂起。 两者的组合 1. 同步阻塞 : 同步阻塞基本也是编程中最常见的模型,打个比方你去商店买衣服,你去了之后发现衣服卖完了,那你就在店里面一直等,期间不做任何事 ( 包括看手机 ) ,等着商家进货,直到有货为止,这个效率很低。 2. 同步非阻塞 : 同步非阻塞在编程中可以抽象为一个轮询模式,你去了商店之后,发现衣服卖完了,这个时候不需要傻傻的等着,你可以去其他地方比如奶茶店,买杯水,但是你还是需要时不时的去商店问老板新衣服到了吗。 3. 异步阻塞 : 异步阻塞这个编程里面用的较少,有点类似你写了个线程池 ,submit 然后马上 future.get () ,这样线程其实还是挂起的。有点像你去商店买衣服,这个时候发现衣服没有了,这个时候你就给老板留给电话,说衣服到了就给我打电话,然后你就守着这个电话,一直等着他响什么事也不做。这样感觉的确有点傻,所以这个模式用得比较少。 4. 异步非阻塞 : 异步非阻塞

IO多路复用之select poll epoll

夙愿已清 提交于 2020-03-24 11:31:37
参考文档: http://blog.csdn.net/tennysonsky/article/details/45745887 select(),poll(),epoll()都是I/O多路复用的机制。I/O多路复用通过一种机制, 可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪,就是这个文件描述符进行读写操作之前),能够通知程序进行相应的读写操作 。 但select(),poll(),epoll()本质上都是同步I/O ,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。 与多线程和多进程相比,I/O 多路复用的最大优势是系统开销小,系统不需要建立新的进程或者线程,也不必维护这些线程和进程。 select 监视并等待多个文件描述符的属性变化(可读、可写或错误异常) select()函数监视的文件描述符分 3 类,分别是writefds、readfds、和 exceptfds 调用后 select() 函数会阻塞,直到有描述符就绪(有数据可读、可写、或者有错误异常),或者超时( timeout 指定等待时间),函数才返回 当 select()函数返回后,可以通过遍历 fdset,来找到就绪的描述符 int select(int nfds, fd_set

I/O 多路复用之select、poll、epoll详解

风流意气都作罢 提交于 2020-03-24 11:13:34
  select,poll,epoll都是IO多路复用的机制。I/O多路复用就是 通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。 但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。 1.select   select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述副就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以 通过遍历fdset,来找到就绪的描述符。    select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点 。select的一 个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但是这样也会造成效率的降低。   select有3个缺点:     每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大。  

聊聊IO多路复用之select、poll、epoll详解

南笙酒味 提交于 2020-03-22 23:41:55
IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。IO多路复用适用如下场合: 当客户处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用。 当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。 如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。 如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。 如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用。 与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。 目前支持I/O多路复用的系统调用有 select,pselect,poll,epoll,I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,pselect,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。 对于IO多路复用机制不理解的同学,可以先行参考《聊聊Linux 五种IO模型》,来了解Linux五种IO模型。

dup与dup2函数

試著忘記壹切 提交于 2020-03-20 12:30:09
依赖的头文件 #include <unistd.h> 函数定义 int dup(int oldfd); int dup2(int oldfd, int newfd); 函数作用 dup和dup2都可用来复制一个现存的文件描述符,使两个文件描述符指向同一个file结构体。 如果两个文件描述符指向同一个file结构体,File Status Flag和读写位置只保存一份在file结构体中,并且file结构体的引用计数是2。 如果两次open同一文件得到两个文件描述符,则每个描述符对应一个不同的file结构体,可以有不同的File Status Flag和读写位置。 实战 需求:在代码中执行2次printf("hello Linux\n"),前一次输入到world文件中,后一次输入到屏幕上 #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> void file_Redirect() { //先备份现场 int outfd = dup(1); //先做重定向 int fd = open("world", O_WRONLY|O_CREAT,0666); //标准输出到重定向fd到对应的文件 dup2(fd, 1); printf(