linux下c语言pipe无名管道 main函数创建两个进程p1和p2,p1把一个文件名通过管道给main进程,main进程打开

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux下c语言pipe无名管道 main函数创建两个进程p1和p2,p1把一个文件名通过管道给main进程,main进程打开相关的知识,希望对你有一定的参考价值。

linux下c语言pipe无名管道 main函数创建两个进程p1和p2,p1把一个文件名通过管道给main进程,main进程打开文件,读出内容,发给p2,p2进程打印,并将内容返回p1,p1将内容重新写入另外一个文件中

#include <stdio.h>
main()

int i,r,p1,p2,fd[2];
char buf[50],s[50];
pipe(fd); //创建匿名管道,fd[0]为读端,fd[1]为写端
while((p1=fork())==-1); //创建子进程P1,直至成功为止(p1!=-1)
if(p1==0) //子进程P1执行逻辑

lockf(fd[1],1,0); //锁定管道写端,保证写入数据的完整性
sprintf(buf,"child process P1 is sending messages!\n"); //在buf中填入准备写入管道的信息数据
printf("child processP1!\n"); //打印“子进程P1正在运行”
write(fd[1],buf,50); //向管道写端fd[1]写入buf中的数据,写完后该数据即可以从读端fd[0]读出
sleep(5); //睡眠5秒
lockf(fd[1],0,0); //解锁管道写端
exit(0); //子进程P1退出

else //主进程的执行逻辑

while((p2=fork())==-1); //创建第二个子进程P2
if(p2==0) //子进程P2的执行逻辑

lockf(fd[1],1,0); //锁定管道写端,保证数据写入完整
sprintf(buf,"child process P2 is sending messages!\n"); //在buf中填入准备写入管道的信息数据
printf("child processP2!\n"); //打印“子进程P2正在运行”
write(fd[1],buf,50); //向管道写端fd[1]写入buf中的数据,写完后该数据即可从读端fd[0]读出
sleep(5); //睡眠5秒
lockf(fd[1],0,0); //解锁管道写端
exit(0); //子进程P2退出

//以下为主进程执行逻辑
wait(0); //等待某个子进程退出
if(r=read(fd[0],s,50)==-1) //从管道读端fd[0]读取P1或者P2写入的数据(视哪个子进程抢先执行到lockf函数)

printf(:can't read pipe\n"); //读取失败,打印错误信息

else

printf(:%s\n",s); //打印出读到的信息数据

wait(0); //等待第二个子进程退出
if(r=read(fd[0],s,50)==-1) //从管道读端fd[0]读取出P1或者P2写入的数据(视哪个子进程后执行到lockf函数)

printf(:can't read pipe\n"); //读取失败,打印错误信息

else

printf(:%s\n",s); //打印读取到的信息数据

exit(0); //主进程退出



总的说来,就是主进程创建了两个子进程P1、P2,这两个子进程分别向管道写入了一行文字,然后主进程从管道另一端将这两行文字读出并打印出来
由于进程的并发执行性,哪个子进程的信息先写到管道是随机的,因此该程序每次运行的输出可能并不相同,两行文字之间可能会相互交换
参考技术A template<typename T>
const T& Max(vector<T>& vt)

int max_idx=0;
for(int i=1;i<vt.size();i++)
if(vt[i] > vt[max_idx])
max_idx = i;
return vt[max_idx];


差不多就这样了,自己处理一下边界条件(比如数据为空等检查)本回答被提问者采纳
参考技术B 你说的不太明白,你试试下面这个程序,是那个意思吗
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
//#include<string.h>
#include<fcntl.h>
#include<signal.h>

#define MAXSIZE 256

void sig_info(int signo)

wait(NULL);


int main(int argc,char *argv[])

int fin,fd[2];

if(signal(SIGCHLD,sig_info)==SIG_ERR)

perror("SIGCHLD error");
exit(EXIT_FAILURE);

if(pipe(fd)<0)

perror("pipe error");
exit(EXIT_FAILURE);


pid_t pid;

if((pid=fork())<0)

perror("fork error");
exit(EXIT_FAILURE);

else if(pid==0)

//printf("in child\n");
close(fd[1]);
//sleep(2);
if(fd[0]!=STDIN_FILENO)

dup2(fd[0],STDIN_FILENO);

if(execl("/bin/cat","cat",(char *)0)<0)

perror("execlp error");
exit(EXIT_FAILURE);

close(fd[0]);

else

//printf("in parent\n");
close(fd[0]);
if((fin=open(argv[1],O_RDONLY))<0)

perror("open error");
exit(EXIT_FAILURE);

char buffer[MAXSIZE];
int nread;
//printf("in parent\n");
if((nread=read(fin,buffer,MAXSIZE))>0)


if(write(fd[1],buffer,nread)!=nread)

perror("write error");
exit(EXIT_FAILURE);

// printf("fd :%s\n",buffer);

close(fd[1]);
//exit(0);
//wait(NULL);

linux进程间通信之一:无名管道

  无名管道是linux中管道通信的一种原始方法,有以下特征:

  1、单工通信模式,具有固定的读端和写端;

  2、管道可以看成是一种特殊的文件,对于它的读写可以使用普通的read(),write()等文件IO操作函数接口,但是它不属于任何文件系统,并且只存在与内存中;

  3、只能用于具有亲缘关系的进程之间的通信;

  4、通常使用时,首先创建一个管道,然后调用fork函数创建一个子进程,该子进程会继承父进程所创建的管道;

  5、只有在管道的读端存在时,向管道写入数据才有意义,否则向管道写入的数据的进程将收到内核发送过来的SIGPEPE信号;

  6、向管道写入数据时,linux不保证写入的原子性,管道缓冲区只要有空间,写进程就会试图向管道写入数据,如果管道缓冲区已满,那么写操作将会一直阻塞;

下面例子详尽阐述管道的使用方法,首先创建管道,然后父进程使用fork函数创建子进程,最后通过关闭父进程的读描述符和子进程的写描述符,建立它们之间的通信,父子进程的先后顺序通过信号量PV操作来实现;图1为详尽实现代码,图2为编译运行后结果。

 

以上是关于linux下c语言pipe无名管道 main函数创建两个进程p1和p2,p1把一个文件名通过管道给main进程,main进程打开的主要内容,如果未能解决你的问题,请参考以下文章

linux 管道实现解析

linux之无名管道

IPC通信_无名管道(PIPE)

Linux系统编程—管道

多进程编程之进程间通信-管道和消息队列

进程之间通信之有名管道无名管道(pipe),笔记