如何 write/read 多次到一个管道
How to write/read multiple times to a pipe
我正在尝试让两个 child 进程通过 pipe.First 相互通信 child 必须写入数据 1 和数据 2,然后是第二个 child写入数据3和数据4。然后childrens互相读取数据并打印。这是我到目前为止的代码。它只显示 children 互相发送的第一条消息,然后挂起。
#include <stdio.h>
#include <sys/types.h>
int main(void) {
pid_t child_a, child_b;
int pipe_a[2],pipe_b[2];
char mesazhi1[] = "First message";
char mesazhi2[] = "Second message";
char buf[50];
int first_pipe = pipe(pipe_a);
int second_pipe = pipe(pipe_b);
if(first_pipe == -1 || second_pipe == -1 ){
perror("pipe");
exit(1);
}
child_a = fork();
if (child_a == 0) {
/* Child A code */
printf("%s\n","the first child is writing to pipe a" );
write(pipe_a[1],mesazhi1, sizeof(mesazhi1));
write(pipe_a[1],mesazhi2,sizeof(mesazhi2));
while( read(pipe_b[0],buf,sizeof(buf) + sizeof(buf) ) > 0 ){
printf("Reading from buffer for child 1 gives: %s \n",buf);
}
} else {
child_b = fork();
if (child_b == 0) {
/* Child B code */
printf("%s\n","the second child is writing to pipe b" );
write(pipe_b[1],mesazhi2,sizeof(mesazhi2));
while( read(pipe_a[0],buf,sizeof(buf) +sizeof(buf) ) > 0 ){
printf("Reading from buffer for child 2 gives: %s \n",buf);
}
write(pipe_b[1],mesazhi1,sizeof(mesazhi1));
printf("%s\n","the second child reads data from pipe a" );
} else {
/* Parent Code */
int returnStatusA,returnStatusB;
waitpid(child_a, &returnStatusA, 0); // Parent process waits here for child to terminate.
waitpid(child_b, &returnStatusB, 0); // Parent process waits here for child to terminate.
if (returnStatusA == 0 && returnStatusB == 0) // Verify child process terminated without error.
{
printf("%s\n", "The child processes terminated normally.\n");
}
if (returnStatusA == 1 && returnStatusB == 1)
{
printf("%s\n", "The child processes terminated with an error!. \n" );
}
printf("%s\n","The parent terminates two childs");
}
}
}
您的代码导致 死锁。
您使用 read()
函数的方式有误。 read(pipe_a[0],buf,sizeof(buf) +sizeof(buf) )
您期望缓冲区大小的两倍,并希望将那个数量的字节放入缓冲区。所以 child A 中的 read
等待 pipe_b
,反之亦然。因此 child B 无法写入 pipe_b
,因为它在 waiting.Similarly,child A 无法写入 pipe_a
,因为它正在等待。
此外,您的代码与您在问题中解释的场景不同。在childB你是读后写。
最后使用 strlen()
代替 sizeof
来计算字符串的长度。
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
pid_t child_a, child_b;
int pipe_a[2],pipe_b[2];
char mesazhi1[] = "First message";
char mesazhi2[] = "Second message";
char buf[50];
int first_pipe = pipe(pipe_a);
int second_pipe = pipe(pipe_b);
if(first_pipe == -1 || second_pipe == -1 ){
perror("pipe");
exit(1);
}
child_a = fork();
if (child_a == 0) {
/* Child A code */
printf("%s\n","the first child is writing to pipe a" );
write(pipe_a[1],mesazhi1, strlen(mesazhi1) + 1);
write(pipe_a[1],mesazhi2, strlen(mesazhi2) + 1);
read(pipe_b[0], buf, strlen(mesazhi1) + 1);
printf("Reading from buffer for child 1 gives: %s \n",buf);
read(pipe_b[0], buf, strlen(mesazhi2) + 1);
printf("Reading from buffer for child 1 gives: %s \n",buf);
} else {
child_b = fork();
if (child_b == 0) {
/* Child B code */
printf("%s\n","the second child is writing to pipe b" );
read(pipe_a[0],buf, strlen(mesazhi1) + 1);
printf("Reading from buffer for child 2 gives: %s \n",buf);
read(pipe_a[0],buf, strlen(mesazhi2) + 1);
printf("Reading from buffer for child 2 gives: %s \n",buf);
write(pipe_b[1],mesazhi1, strlen(mesazhi1) + 1);
write(pipe_b[1],mesazhi2, strlen(mesazhi2) + 1);
printf("%s\n","the second child reads data from pipe a" );
} else {
/* Parent Code */
int returnStatusA,returnStatusB;
waitpid(child_a, &returnStatusA, 0); // Parent process waits here for child to terminate.
waitpid(child_b, &returnStatusB, 0); // Parent process waits here for child to terminate.
if (returnStatusA == 0 && returnStatusB == 0) // Verify child process terminated without error.
{
printf("%s\n", "The child processes terminated normally.\n");
}
if (returnStatusA == 1 && returnStatusB == 1)
{
printf("%s\n", "The child processes terminated with an error!. \n" );
}
printf("%s\n","The parent terminates two childs");
}
}
}
我正在尝试让两个 child 进程通过 pipe.First 相互通信 child 必须写入数据 1 和数据 2,然后是第二个 child写入数据3和数据4。然后childrens互相读取数据并打印。这是我到目前为止的代码。它只显示 children 互相发送的第一条消息,然后挂起。
#include <stdio.h>
#include <sys/types.h>
int main(void) {
pid_t child_a, child_b;
int pipe_a[2],pipe_b[2];
char mesazhi1[] = "First message";
char mesazhi2[] = "Second message";
char buf[50];
int first_pipe = pipe(pipe_a);
int second_pipe = pipe(pipe_b);
if(first_pipe == -1 || second_pipe == -1 ){
perror("pipe");
exit(1);
}
child_a = fork();
if (child_a == 0) {
/* Child A code */
printf("%s\n","the first child is writing to pipe a" );
write(pipe_a[1],mesazhi1, sizeof(mesazhi1));
write(pipe_a[1],mesazhi2,sizeof(mesazhi2));
while( read(pipe_b[0],buf,sizeof(buf) + sizeof(buf) ) > 0 ){
printf("Reading from buffer for child 1 gives: %s \n",buf);
}
} else {
child_b = fork();
if (child_b == 0) {
/* Child B code */
printf("%s\n","the second child is writing to pipe b" );
write(pipe_b[1],mesazhi2,sizeof(mesazhi2));
while( read(pipe_a[0],buf,sizeof(buf) +sizeof(buf) ) > 0 ){
printf("Reading from buffer for child 2 gives: %s \n",buf);
}
write(pipe_b[1],mesazhi1,sizeof(mesazhi1));
printf("%s\n","the second child reads data from pipe a" );
} else {
/* Parent Code */
int returnStatusA,returnStatusB;
waitpid(child_a, &returnStatusA, 0); // Parent process waits here for child to terminate.
waitpid(child_b, &returnStatusB, 0); // Parent process waits here for child to terminate.
if (returnStatusA == 0 && returnStatusB == 0) // Verify child process terminated without error.
{
printf("%s\n", "The child processes terminated normally.\n");
}
if (returnStatusA == 1 && returnStatusB == 1)
{
printf("%s\n", "The child processes terminated with an error!. \n" );
}
printf("%s\n","The parent terminates two childs");
}
}
}
您的代码导致 死锁。
您使用 read()
函数的方式有误。 read(pipe_a[0],buf,sizeof(buf) +sizeof(buf) )
您期望缓冲区大小的两倍,并希望将那个数量的字节放入缓冲区。所以 child A 中的 read
等待 pipe_b
,反之亦然。因此 child B 无法写入 pipe_b
,因为它在 waiting.Similarly,child A 无法写入 pipe_a
,因为它正在等待。
此外,您的代码与您在问题中解释的场景不同。在childB你是读后写。
最后使用 strlen()
代替 sizeof
来计算字符串的长度。
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
pid_t child_a, child_b;
int pipe_a[2],pipe_b[2];
char mesazhi1[] = "First message";
char mesazhi2[] = "Second message";
char buf[50];
int first_pipe = pipe(pipe_a);
int second_pipe = pipe(pipe_b);
if(first_pipe == -1 || second_pipe == -1 ){
perror("pipe");
exit(1);
}
child_a = fork();
if (child_a == 0) {
/* Child A code */
printf("%s\n","the first child is writing to pipe a" );
write(pipe_a[1],mesazhi1, strlen(mesazhi1) + 1);
write(pipe_a[1],mesazhi2, strlen(mesazhi2) + 1);
read(pipe_b[0], buf, strlen(mesazhi1) + 1);
printf("Reading from buffer for child 1 gives: %s \n",buf);
read(pipe_b[0], buf, strlen(mesazhi2) + 1);
printf("Reading from buffer for child 1 gives: %s \n",buf);
} else {
child_b = fork();
if (child_b == 0) {
/* Child B code */
printf("%s\n","the second child is writing to pipe b" );
read(pipe_a[0],buf, strlen(mesazhi1) + 1);
printf("Reading from buffer for child 2 gives: %s \n",buf);
read(pipe_a[0],buf, strlen(mesazhi2) + 1);
printf("Reading from buffer for child 2 gives: %s \n",buf);
write(pipe_b[1],mesazhi1, strlen(mesazhi1) + 1);
write(pipe_b[1],mesazhi2, strlen(mesazhi2) + 1);
printf("%s\n","the second child reads data from pipe a" );
} else {
/* Parent Code */
int returnStatusA,returnStatusB;
waitpid(child_a, &returnStatusA, 0); // Parent process waits here for child to terminate.
waitpid(child_b, &returnStatusB, 0); // Parent process waits here for child to terminate.
if (returnStatusA == 0 && returnStatusB == 0) // Verify child process terminated without error.
{
printf("%s\n", "The child processes terminated normally.\n");
}
if (returnStatusA == 1 && returnStatusB == 1)
{
printf("%s\n", "The child processes terminated with an error!. \n" );
}
printf("%s\n","The parent terminates two childs");
}
}
}