linux无名管道
特点
无名管道是半双工的,也就是说,一个管道要么只能读,要么只能写
只能在有共同祖先的进程间使用(父子进程、兄弟进程、子孙进程等)
fork或者execve调用创建的子进程,继承了父进程的文件描述符
通过man 2 pipe查看
1 2 | #include <unistd.h> int pipe( int pipefd[2]); |
打开两个文件描述符,保存在pipefd中,其中pipefd[0]为读端,pipefd[1]为写端
无名管道写入操作不具有原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。
不能使用lseek来定位
如果函数出错,返回值为-1,并设置errno
关闭管道用close函数
如果只有写管道,没有读管道,内核会发送SIFPIPE信号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { int pipefd[2] = {0}; if (-1 == pipe(pipefd)) { fprintf (stderr, "pipe: %d, %s\n" , errno , strerror ( errno )); exit (1); } pid_t pid = fork(); if (pid < 0) { fprintf (stderr, "fork: %d, %s\n" , errno , strerror ( errno )); exit (1); } if (pid > 0) { close(pipefd[0]); char buf[] = "data from parent programe." ; write(pipefd[1], buf, strlen (buf)); close(pipefd[1]); } else { close(pipefd[1]); char buf[60] = {0}; int readlen = read(pipefd[0], buf, 60); printf ( "child read length: %d, %s\n" , readlen, buf); close(pipefd[0]); wait(NULL); } return 0; } |
管道局限性
- 只支持单向数据流
- 只能用于亲缘进程之间
- 没有名字
- 缓冲区有限(管道存在于内存中,创建管道时,分配缓冲区)
- 管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,比如多少字节算作一个消息(或命令、或记录)等等;
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步