十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
fork ----- fork ----- fork
网站建设哪家好,找成都创新互联!专注于网页设计、网站建设、微信开发、小程序开发、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了松阳免费建站欢迎大家使用!
加入进程A fork出了进程B,然后进程B又fork出了进程C,进程C又fork出了进程D
pipe是管道,只有一个入口,一个出口。可以把入口和出口分别放到父子进程中。
父进程负责读,子进程负责写。或者子进程读,父进程写。
你的例子里,在进程A里创建管道PipeA,然后fork出进程B。进程AB之间使用PipeA通信。
进程B再创建PipeB,然后进程BC之间使用PipeB通信。
进程C再创建PipeC,然后进程CD之间使用PipeC通信。
如果想把进程A的数据传递给进程D,那么应该:进程A向PipeA写入数据,进程B从PipeA中读取数据,然后再写入PipeB,进程C从PipeB中读取数据,然后再写入PipeC,进程D从PipeC中读取数据
#include stdio.h
#include stdlib.h
#include string.h
#include assert.h
int main(int argc,char *argv[])
{
int pd[2];/*用于保存管道文件描述符*/
char out[80],str[]="safasfsa";/*str是要写入的字符串,out用于保存从管道读取的字符串*/
assert(pipe(pd)!=-1);/*断言用于确定pipe()函数执行成功,如果管道创建失败,则pipe()返回-1*/
if (!fork()) write(pd[1],str,strlen(str));/*创建子进程,并将字符串写入管道*/
else {
read(pd[0],out,strlen(str));/*在主进程中从管道中读取子进程写入的字符串*/
printf("%s\n",out);/*主进程中输出。*/
}
return 0;
}
你好,
用gets会有越界问题,建议使用fgets。
代码如下:
#include stdio.h
#include unistd.h
#include stdlib.h
int main(int argc, const char *argv[])
{
pid_t pid;
int fd[2];
pipe(fd);
pid = fork();
if (pid == -1) {
perror("fork");
return -1;
} else if (pid == 0) { //子进程
char buf[128] = {0};
close(fd[1]);//关闭了写,具有读管道权限
read(fd[0], buf, sizeof(buf));
printf("read from parent:%s\n", buf);
close(fd[0]);
} else { //父进程
char buf[128] = {0};
close(fd[0]);//关闭读,具有写管道权限
gets(buf);
printf("write to child\n");
write(fd[1], buf, sizeof(buf));
close(fd[1]);
}
return 0;
}
祝你生活愉快。
创建管道时返回的是一对文件描述符,fd[0]读,fd[1]写,这个是pipe()函数的固定实现。
要说为什么的话,管道是半双工的,一端写入数据流,一端读出数据流,所以至少需要两个文件描述符,一个读一个写。
handlesSimpleCmdStr(inputbuf)该函数调用地点先于定义,应该将定义提前或者将声明写在定义之前,还有问题需注意,函数的实现放在头文件里,在编译的时候头文件的内容会替换#include,如果头文件没处理好,可能有些问题会有些让人无语
#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,这两个子进程分别向管道写入了一行文字,然后主进程从管道另一端将这两行文字读出并打印出来
由于进程的并发执行性,哪个子进程的信息先写到管道是随机的,因此该程序每次运行的输出可能并不相同,两行文字之间可能会相互交换