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进程打开的主要内容,如果未能解决你的问题,请参考以下文章