管道的使用
管道的使用
管道用在Linux的进程通信中,只能用在具有血缘关系的进程中。管道本质就是一段内存缓冲区,一个进程有写权限,另一个有读权限。
在c/c++中,我们可以使用pipe创建一个管道。show you the code:
int pipe (int fd[2]);
// 参数
// fd[0] : 读端
// fd[1] : 写端
#include <stdio.h>
#include <unistd.h>
int main() {
int fd[2];
pipe(fd);
int pid = fork();
if (pid == 0) {
// 子进程
int num;
// 关闭管道的写端口
close(fd[1]);
while (read(fd[0], &num, sizeof(int)) != 0) {
printf("num %d\n", num);
}
// 关闭管道的读端口
close(fd[0]);
} else if (pid > 0) {
// 关闭管道的读端口
close(fd[0]);
for (int i = 1; i <= 10; i++) {
write(fd[1], &i, sizeof(i));
}
// 关闭管道的写端口
close(fd[1]);
}
return 0;
}
最后输出--1 2 .... 10。
需要创建一个数组,用pipe函数将数组变为管道。变为管道后,fd[0]是读的端口,fd[1]是写的端口。这里父进程通过管道向子进程输入数字,然后子进程打印数字。因为父进程是要写,所以写之前要关闭读的端口close fd[0],然后通过写端口将数字传入子进程,写完之后要关闭写的端口close fd[1],防止子进程读取的时候发生阻塞使子程序一直运行。
的使用方法:write()
和
read()
- wirte()
第一个参数是管道的写端口(记的之前要关闭管道的读端口,读完之后关闭管道的写端口),第二个参数是需要写入的数据的地址,第三个参数是写入数据的大小。
- read()
第一个参数是管道的读端口(记的之前要关闭管道的写端口,读完之后关闭管道的读端口),第二个参数是需要将读取的数据放在的地址,第三个参数是读取数据的大小。
注意:
- 1、
之前关闭管道的读端口,读完之后关闭管道的写端口wirte()
- 2、
之前要关闭管道的写端口,读完之后关闭管道的读端口read()
缺点:
- 1、单工通信。只能一个进程写,一个进程读,如果要双向通信需要创建两个管道。
- 2、只有有血缘关系的进程才可以通信。
四种特殊情况
- 当管道的所有写端的描述符都关闭了,还要进程在读取,read()会返回一个0。
#include <stdio.h>
#include <unistd.h>
#include <wait.h>
int main() {
int fd[2];
pipe(fd);
int status = -1;
int pid = fork();
if (pid == 0) {
close(fd[1]);
int i;
while (1) {
ssize_t ret = read(fd[0], &i, sizeof(i));
if (ret == 0) {
printf("pipe is empty\n");
return 0;
}
printf("%d ", i);
}
close(fd[0]);
} else if (pid > 0) {
// 父进程
close(fd[0]);
for (int i = 1; i <= 10; i++) {
write(fd[1], &i, sizeof(i));
}
close(fd[1]);
wait(&status);
}
return 0;
}
最后输出
。1 2 3 4 5 6 7 8 9 10 pipe is empty
版权声明:
作者:徐锦桐
链接:https://www.xujintong.com/2023/11/19/178/
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
作者:徐锦桐
链接:https://www.xujintong.com/2023/11/19/178/
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
THE END