APUE-Learning-高级IO
高级I/O
- I/O多路复用
- 有多个描述符,数据可能在任一个描述符上到达(可用),但是事先无法知道究竟是哪一个描述符
- 不能对任意一个描述符进行阻塞读操作,因为数据可能已经在其它描述符上到达
- 使用两个或多个进程/线程分别处理一个描述符,但是带来资源开销、同步处理的问题
- 不使用阻塞I/O:对所有描述符进行轮询处理
- 异步I/O+信号:信号数量有限,无法与描述符一一对应
- I/O多路复用:实现准备一张描述符表,内核会在表中任一个描述符准备好时,通知进程并告知哪些文件描述符已经准备好了
- 有三个select,poll,epoll;均会阻塞线程,直到有可用的描述符时才会返回
- 描述符集:fd_set
- select: 三组描述符集作为参数(可读、可写、异常条件)
- poll: pollfd数组:包含描述符编号、感兴趣的事件
进程间通信
无名管道
- 只能在两个相关的进程间使用;即两个fd通过父进程创建,之后在子进程中使用
有名管道(FIFO)
- 不相关的进程间也能通信
- 它是一种文件类型,它的文件名(路径名)存在于文件系统中
int mkfifo(const char* path, mode_t mode);,返回值为文件描述符
三个相似的IPC机制
- 使用键(key_t)来标识
key_t ftok(const char* path, int id),根据一个路径名和ID,创建一个key
- 消息队列(1)
msgget(key_t, int),【创建或打开已有的】返回非负队列ID,供后续发送、接收、控制使用
- 信号量(2)
semget(key_t, int)- 删除是立即生效的;会导致其它使用该信号量的程序产生错误
- 共享内存(3)
shmget(key_t, int)
POSIX 信号量
- 更高性能
- 接口更简单
- 添加引用计数,删除操作会在最后一次引用结束时删除信号量
sem_t* sem_open(const char* name, int flag, ...),创建新的或打开一个已有的信号量sem_close()操作并不会将信号量值减1
APUE-Learning-高级IO
http://example.com/2024/07/22/APUE-Learning-高级IO/