pipe() 匿名管道
- 创建匿名管道 局限性:两端进程须具有共同祖先 及文件描述符指向同一文件
成功返回0,失败返回-1
#include <unistd.h>
int pipe(int pipefd[2]);
- 数组第一个元素为读取数据的文件描述符
第二个元素为写入数据的文件描述符 - 例子: 实现输出Hello world!
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
int main() {
int fd[2], n, buf[20];
if (pipe(fd) < 0) {
perror("pipe");
exit(1);
}
pid_t pid = fork();
if (pid < 0){
perror("fork");
exit(1);
}
if (pid) {
close(fd[0]); //父进程关闭匿名管道读端
write(fd[1], "Hello world!\n", 13);
wait(NULL); //阻塞等待子进程结束
} else {
close(fd[1]); //子进程关闭匿名管道写端
n = read(fd[0], buf, 20);
write(1, buf, n);
}
return 0;
}
mkfifo() 命名管道
- 命名管道创建以后可以被任何进程像文件一样使用,须读写进程必须同时出现
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char* pathname, mode_t mode);
- 第一个形参为管道名称;第二个形参为命名管道权限可被umask命令修改
epoll()
- 用于一段时间内同时候等待多个文件产生I/O事件。由3个函数组成
-
epoll_create()
#include <sys/epoll.h> //初始化epoll() 返回非零文件描述符 int epoll_create(int size); //Linux2.6.8之后不需要参数,但须指定大于0的参数兼容老版本
-
epoll_ctl()
#include <sys/epoll.h> //加入新的等待事件、删除等待事件、修改现有的等待事件。成功返回0,否则返回-1 int epoll_ctl(int epfd, int op, int fd, struct epoll_event* event);
-
第一个形参epfd:epoll()实例的文件描述符,即epoll_create()返回值
-
op:1)EPOLL_CTL_ADD 添加新的文件描述符;
2)EPOLL_CTL_MOD 修改一个正在被监控的文件描述符;
3)EPOLL_CTL_DEL 删除一个正在被监控的文件描述符
-
fd:被添加、修改、删除的I/O事件所关联的文件
-
event:指向文件描述符监控的事件
typedef union epoll_data { void* ptr; int fd; //文件描述符 unsigned int u32; unsigned long long u64; } epoll_data_t; struct epoll_event { uint32_t events; //Epoll events:由或运算连接在一起的事件 epoll_data_t data; /*User data variable*/ };
events: EPOLLIN 文件有数据可供读取
---------- EPOLLOUT 文件可以被写入数据
--------- EPOLLERR 文件出现错误 epoll()默认监控次事件
--------- EPOLLHUP 文件被挂起 epoll()默认监控次事件
-
epoll_wait()
#include <sys/epoll.h> //等待i/O事件发送 返回实际产生数量;0表示立即返回没有事件产生;负值会一直等待事件发送再返回 int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);
maxevents表示events的数量,timeout记录次毫秒内实际产生的事件