C中的管道 - 在我的程序中读写
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C中的管道 - 在我的程序中读写相关的知识,希望对你有一定的参考价值。
我希望我的程序显示如下结果:
child: 2 4 6 8 10
parent: 3 6 9 12 15
child 12 14 16 18 20
parent 18 21 24 27 30
等等
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
main(int argc,char *argv[]){
int i=0,tube1[2],tube2[2],pid,tube3[2];
if(pipe(tube1)||pipe(tube2)==-1){
perror("pipe");
exit(0);
}
pid=fork();
while(i<100){
if(pid==0){
printf("fils ");
do{
i=i+2;
printf("%d ",i);
}while(i%5!=0);
write(tube1[1],&i,sizeof(int));
read(tube2[0],&i,sizeof(int));
}
else{
printf("pere ");
read(tube1[0],&i,sizeof(int));
do{
i=i+3;
printf("%d ",i);
}while(i%5!=0);
write(tube2[1],&i,sizeof(int));
}
printf("\n");
}
close(tube1[1]);
close(tube1[0]);
close(tube2[1]);
close(tube2[0]);
}
但我的课程有问题;我不懂为什么。
清理后,您的代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int i = 0, tube1[2], tube2[2], pid;
if (pipe(tube1) == -1 || pipe(tube2) == -1)
{
perror("pipe");
exit(0);
}
pid = fork();
while (i < 100)
{
if (pid == 0)
{
printf("fils ");
do
{
i = i + 2;
printf("%d ", i);
} while (i % 5 != 0);
putchar('\n');
write(tube1[1], &i, sizeof(int));
read(tube2[0], &i, sizeof(int));
}
else
{
printf("pere ");
read(tube1[0], &i, sizeof(int));
do
{
i = i + 3;
printf("%d ", i);
} while (i % 5 != 0);
putchar('\n');
write(tube2[1], &i, sizeof(int));
}
}
close(tube1[1]);
close(tube1[0]);
close(tube2[1]);
close(tube2[0]);
}
一个变化是进程在写入一系列数字后输出换行符,而不是等到读/写操作之后。
循环是复杂的,因为你有一个外部while (i < 100)
循环,然后每个进程都有一个内循环,增加i
。然后,为了使事情进一步复杂化,孩子将其当前的i
值发送给父母,并且父母在其循环中使用它,然后父母将其自己的i
值发送给孩子并且孩子继续使用新的i
的价值;冲洗并重复。输出是:
fils 2 4 6 8 10
pere 13 16 19 22 25
fils 27 29 31 33 35
pere 38 41 44 47 50
fils 52 54 56 58 60
pere 63 66 69 72 75
fils 77 79 81 83 85
pere 88 91 94 97 100
您可以看到孩子生成的值为10;那么父母将它从孩子那里得到的值加上3(因此是13)并迭代;然后它向孩子发送25,这增加2(因此27)并迭代;等等。
要获得您要搜索的结果,您需要从值中分离同步中使用的值以控制循环。你也遇到了一个问题,因为孩子会尝试比父母跑更长的时间,但幸运的是,它会得到一个SIGPIPE信号,当它试图写入父母已关闭的管道时会死亡 - 或者说,如果它关闭了它没有使用的管道的末端。生成换行符后刷新标准输出也是一个好主意。这些变化导致:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int i = 0, tube1[2], tube2[2], pid;
if (pipe(tube1) == -1 || pipe(tube2) == -1)
{
perror("pipe");
exit(1);
}
pid = fork();
if (pid < 0)
{
perror("fork");
exit(1);
}
if (pid == 0)
{
close(tube1[0]);
close(tube2[1]);
}
else
{
close(tube1[1]);
close(tube2[0]);
}
while (i < 100)
{
if (pid == 0)
{
printf("fils ");
do
{
i = i + 2;
printf("%d ", i);
} while (i % 5 != 0);
putchar('\n');
fflush(stdout);
int j = 0;
write(tube1[1], &j, sizeof(int));
read(tube2[0], &j, sizeof(int));
}
else
{
int j = 0;
read(tube1[0], &j, sizeof(int));
printf("pere ");
do
{
i = i + 3;
printf("%d ", i);
} while (i % 5 != 0);
putchar('\n');
fflush(stdout);
write(tube2[1], &j, sizeof(int));
}
}
close(tube1[1]);
close(tube1[0]);
close(tube2[1]);
close(tube2[0]);
}
而那个输出是:
fils 2 4 6 8 10
pere 3 6 9 12 15
fils 12 14 16 18 20
pere 18 21 24 27 30
fils 22 24 26 28 30
pere 33 36 39 42 45
fils 32 34 36 38 40
pere 48 51 54 57 60
fils 42 44 46 48 50
pere 63 66 69 72 75
fils 52 54 56 58 60
pere 78 81 84 87 90
fils 62 64 66 68 70
pere 93 96 99 102 105
fils 72 74 76 78 80
请注意,子项未达到100,因为父项退出,并且父项超过100,因为检查发生在外部循环上,而不是内部循环上。
我保留了你的循环组织,但它是我自己的代码,它将有两个函数 - be_childish()
和be_parental()
- 它们将在fork之后调用,并且每个函数都将运行它们自己的相关循环。管道将传递给功能部件,他们会更好地清理。请注意,程序结束时4个close()
调用中的2个将失败,因为这些管道描述符先前已关闭。分开哪些是繁琐的;最好将代码拆分为函数。
以上是关于C中的管道 - 在我的程序中读写的主要内容,如果未能解决你的问题,请参考以下文章
C++ 管道/ReadFile lpNumberOfBytesRead/DLL
当我点击我的应用程序中的注册用户片段时应用程序崩溃..其中包含recyclerview