管道的概念
- 管道是一种最基本的IPC(进程间通信)机制,作用于有缘关系的进程间,调用pipe() 即可创建一个管道。它有如下特质:
1. 本质是一个伪文件(实为内核缓冲区)
2. 由两个文件描述符引用,一个表示读,一个表示写
3. 规定数据从管道的写端流入管道,读端流出管道
- 管道原理:内核使用环形队列,借助内核缓冲区(默认4K,可以使用ulimit –a 命令来查看)实现。
- 管道的局限性:
1.数据不能自己读,再自己写
2. 数据一旦被读走,便不存在,不可反复读取
3. 采用半双工通信,数据同时只能一个方向流动
4. 只能在有血缘关系的进程间通信
pipe()函数
- 函数原型:int pipe(int pipe[2]); 成功:0 失败:-1 设置error
- 函数调用成功返回两个文件描述符,r ,w;不需要open,但是需要close。规定:
fd[0]->r
fd[1]->w
记忆:读写 对应01
代码
- 父进程创建管道,创建子进程,父进程写hello world进 pipe,子进程从pipe中读出来,再打印到屏幕
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
int fd[2];
char buf[512];
int tem=pipe(fd); //创建管道
if(tem==-1)
{
perror("pipe error");
exit(1);
}
pid = fork(); //创建子进程
{
if (pid <0)
{
perror("fork error");
exit(1);
}
else if(pid == 0) //子进程
{
close(fd[1]);//关闭pipe的写端
int num=read(fd[0],buf,512);
if(num == 0)
{
printf("ggn");
}
printf("%sn",buf);
}
else//父进程
{
close(fd[0]); //关闭pipe的读端
write(fd[1],"hello world",sizeof("hello world"));
}
}
return 0;
}
- 使用管道实现父子进程间通信,完成:ls | wc –l。假定父进程实现ls,子进程实现wc。ls命令正常会将结果集写出到stdout,但现在会写入管道的写端;wc –应该从stdin读取数据,但此时会从管道的读端读。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
int fd[2];
pipe(fd);
pid = fork();
if(pid < 0)
{
perror("fork error");
exit(1);
}
else if(pid == 0) //子进程
{
dup2(fd[0],0); //将管道读端复制到 标准输入
close(fd[1]); //关闭写端
execlp("wc","wc","-l",NULL);
}
else //父进程
{
dup2(fd[1],1); //将管道的写端 复制到 表准输出
close(fd[0]); //关闭读端
execlp("ls","ls",NULL);
}
return 0;
}
结果:输出当前目录 ls 列出的文件的个数
- 使用管道实现兄弟进程间通信。 兄:ls 弟: wc -l 父:等待回收子进程。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
int fd[2], i;
pipe(fd);
for (i = 0; i < 2; i++)
{
pid=fork();
if(pid == 0)
{
break;
}
}
if (i == 0)//子1
{
dup2(fd[1], STDOUT_FILENO); //复制 pipe写端 到 标准输出
close(fd[1]);
close(fd[0]); //关闭读写端
execlp("ls", "ls", NULL);
}
else if (i == 1)//子2
{
dup2(fd[0], STDIN_FILENO); //复制 pipe读端 到 标准输入
close(fd[1]); //关闭读 写端
close(fd[0]);
execlp("wc", "wc", "-l", NULL);
} else
{
close(fd[1]);
close(fd[0]);
while(wait(NULL)>0); //两个儿子wait两次
}
return 0;
}
结果:列出当前目录的文件个数
最后
以上就是紧张书包最近收集整理的关于linux系统编程-管道的全部内容,更多相关linux系统编程-管道内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复