Child 进程通过管道发送一个数字,然后等待
Child process sends a number through a pipe, then waits
我正在尝试生成两个与管道连接的 child 进程。
Child 1 应该通过管道将数字发送到 child 2 并且 child 2 应该打印它。我设法做到了,但是当我尝试循环执行此操作时,child 1 每次在发送另一个号码之前等待 1 秒,它不会发送任何内容。
我做错了什么?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <windows.h>
int main(int argc, char *argv[]) {
int fd[2];
pipe(fd);
pid_t pid1 = fork();
if (pid1) {
pid_t pid2 = fork();
if (pid2) { //parent
// do stuff as parent
} else { //child 2
close(fd[1]);
char stringNumberReceived[10];
while (1) {
read(fd[0], stringNumberReceived, sizeof (stringNumberReceived));
printf("number received: %s\n", stringNumberReceived);
}
}
} else {//child 1
close(fd[0]);
int num;
char stringnumber [10];
while (1) {
num = rand();
snprintf(stringnumber, 10, "%d", num);
printf("attempting to sent: %s\n", stringnumber);
write(fd[1], stringnumber, strlen(stringnumber) + 1);
Sleep(1000);
}
}
}
这是你的代码的一个稍微修改过的版本:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
enum { MAX_COUNT = 20 };
int main(void)
{
int fd[2];
pipe(fd);
pid_t pid1 = fork();
if (pid1)
{
pid_t pid2 = fork();
if (pid2) // parent
{
printf("Child 1: %d; child 2: %d\n", (int)pid1, (int)pid2);
close(fd[0]); // Let the child detect EOF!
close(fd[1]); // Let the child detect EOF!
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("PID %d exited with status 0x%.4X\n", corpse, status);
}
else // child 2
{
close(fd[1]);
char stringNumberReceived[10];
int nbytes;
while ((nbytes = read(fd[0], stringNumberReceived, sizeof(stringNumberReceived))) > 0)
printf("number received: %.*s\n", nbytes, stringNumberReceived);
printf("Child 2: EOF or ERR\n");
}
}
else // child 1
{
close(fd[0]);
int num;
char stringnumber[10];
for (int counter = 0; counter < MAX_COUNT; counter++)
{
num = rand();
snprintf(stringnumber, sizeof(stringnumber), "%d", num);
printf("attempting to send: [%s] (len %zu)\n", stringnumber, strlen(stringnumber));
write(fd[1], stringnumber, strlen(stringnumber) + 1);
sleep(1);
}
}
return 0;
}
发生了什么变化?各种各样的东西。您可以忽略大括号位置的变化;那纯粹是装饰品。
- Parent 代码已实现。
- Parent 报告 child 个进程 ID。
- Parent 关闭管道——它既不读也不写。
- Parent 等待 children 死亡,报告状态。
- Child 记录它读取了多少字节,并确保它打印的不超过这个数。
- 当管道上出现错误或 EOF(读取 0 字节)时,它会终止循环并在退出前报告。
- 其他 child 在退出之前执行固定次数的循环(如图所示为 20)。
- 如果随机数生成器生成了 10 位以上的数字,您可能会遇到数组边界问题。我得到的最大长度是9,刚好安全。
- 完成后生成 child could/should 报告。
在更改中,我怀疑 parent 中关闭管道可能是关键。
示例输出(在 Unix 机器上):
$ pp43
attempting to send: [16807] (len 5)
Child 1: 69198; child 2: 69199
number received: 16807
attempting to send: [282475249] (len 9)
number received: 282475249
attempting to send: [162265007] (len 9)
number received: 162265007
attempting to send: [984943658] (len 9)
number received: 984943658
attempting to send: [114410893] (len 9)
number received: 114410893
attempting to send: [470211272] (len 9)
number received: 470211272
attempting to send: [101027544] (len 9)
number received: 101027544
attempting to send: [145785087] (len 9)
number received: 145785087
attempting to send: [145877792] (len 9)
number received: 145877792
attempting to send: [200723770] (len 9)
number received: 200723770
attempting to send: [823564440] (len 9)
number received: 823564440
attempting to send: [111543816] (len 9)
number received: 111543816
attempting to send: [178448449] (len 9)
number received: 178448449
attempting to send: [74243042] (len 8)
number received: 74243042
attempting to send: [114807987] (len 9)
number received: 114807987
attempting to send: [113752250] (len 9)
number received: 113752250
attempting to send: [144128232] (len 9)
number received: 144128232
attempting to send: [16531729] (len 8)
number received: 16531729
attempting to send: [823378840] (len 9)
number received: 823378840
attempting to send: [143542612] (len 9)
number received: 143542612
Child 2: EOF or ERR
PID 69198 exited with status 0x0000
PID 69199 exited with status 0x0000
$
我正在尝试生成两个与管道连接的 child 进程。
Child 1 应该通过管道将数字发送到 child 2 并且 child 2 应该打印它。我设法做到了,但是当我尝试循环执行此操作时,child 1 每次在发送另一个号码之前等待 1 秒,它不会发送任何内容。
我做错了什么?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <windows.h>
int main(int argc, char *argv[]) {
int fd[2];
pipe(fd);
pid_t pid1 = fork();
if (pid1) {
pid_t pid2 = fork();
if (pid2) { //parent
// do stuff as parent
} else { //child 2
close(fd[1]);
char stringNumberReceived[10];
while (1) {
read(fd[0], stringNumberReceived, sizeof (stringNumberReceived));
printf("number received: %s\n", stringNumberReceived);
}
}
} else {//child 1
close(fd[0]);
int num;
char stringnumber [10];
while (1) {
num = rand();
snprintf(stringnumber, 10, "%d", num);
printf("attempting to sent: %s\n", stringnumber);
write(fd[1], stringnumber, strlen(stringnumber) + 1);
Sleep(1000);
}
}
}
这是你的代码的一个稍微修改过的版本:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
enum { MAX_COUNT = 20 };
int main(void)
{
int fd[2];
pipe(fd);
pid_t pid1 = fork();
if (pid1)
{
pid_t pid2 = fork();
if (pid2) // parent
{
printf("Child 1: %d; child 2: %d\n", (int)pid1, (int)pid2);
close(fd[0]); // Let the child detect EOF!
close(fd[1]); // Let the child detect EOF!
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("PID %d exited with status 0x%.4X\n", corpse, status);
}
else // child 2
{
close(fd[1]);
char stringNumberReceived[10];
int nbytes;
while ((nbytes = read(fd[0], stringNumberReceived, sizeof(stringNumberReceived))) > 0)
printf("number received: %.*s\n", nbytes, stringNumberReceived);
printf("Child 2: EOF or ERR\n");
}
}
else // child 1
{
close(fd[0]);
int num;
char stringnumber[10];
for (int counter = 0; counter < MAX_COUNT; counter++)
{
num = rand();
snprintf(stringnumber, sizeof(stringnumber), "%d", num);
printf("attempting to send: [%s] (len %zu)\n", stringnumber, strlen(stringnumber));
write(fd[1], stringnumber, strlen(stringnumber) + 1);
sleep(1);
}
}
return 0;
}
发生了什么变化?各种各样的东西。您可以忽略大括号位置的变化;那纯粹是装饰品。
- Parent 代码已实现。
- Parent 报告 child 个进程 ID。
- Parent 关闭管道——它既不读也不写。
- Parent 等待 children 死亡,报告状态。
- Child 记录它读取了多少字节,并确保它打印的不超过这个数。
- 当管道上出现错误或 EOF(读取 0 字节)时,它会终止循环并在退出前报告。
- 其他 child 在退出之前执行固定次数的循环(如图所示为 20)。
- 如果随机数生成器生成了 10 位以上的数字,您可能会遇到数组边界问题。我得到的最大长度是9,刚好安全。
- 完成后生成 child could/should 报告。
在更改中,我怀疑 parent 中关闭管道可能是关键。
示例输出(在 Unix 机器上):
$ pp43
attempting to send: [16807] (len 5)
Child 1: 69198; child 2: 69199
number received: 16807
attempting to send: [282475249] (len 9)
number received: 282475249
attempting to send: [162265007] (len 9)
number received: 162265007
attempting to send: [984943658] (len 9)
number received: 984943658
attempting to send: [114410893] (len 9)
number received: 114410893
attempting to send: [470211272] (len 9)
number received: 470211272
attempting to send: [101027544] (len 9)
number received: 101027544
attempting to send: [145785087] (len 9)
number received: 145785087
attempting to send: [145877792] (len 9)
number received: 145877792
attempting to send: [200723770] (len 9)
number received: 200723770
attempting to send: [823564440] (len 9)
number received: 823564440
attempting to send: [111543816] (len 9)
number received: 111543816
attempting to send: [178448449] (len 9)
number received: 178448449
attempting to send: [74243042] (len 8)
number received: 74243042
attempting to send: [114807987] (len 9)
number received: 114807987
attempting to send: [113752250] (len 9)
number received: 113752250
attempting to send: [144128232] (len 9)
number received: 144128232
attempting to send: [16531729] (len 8)
number received: 16531729
attempting to send: [823378840] (len 9)
number received: 823378840
attempting to send: [143542612] (len 9)
number received: 143542612
Child 2: EOF or ERR
PID 69198 exited with status 0x0000
PID 69199 exited with status 0x0000
$