子进程在使用父进程将数据写入管道之前读取数据
Child process reads data before data is being written to pipe using parent
我正在使用 fork() 创建一个子进程,在父进程中我输入 5 个整数并将其保存到一个数组中。然后将此数据写入管道。然后子进程将从饼中读取数据并将其打印到屏幕上。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#define INPUT 5
int main() {
int fd[2];
pid_t childprocess;
if((childprocess = fork()) < 0) {
perror("Cannot fork child");
}
if(childprocess > 0) {
// Parent
int userInput[INPUT];
close(fd[0]);
for(int i = 0; i < INPUT; i++) {
printf("Enter number %d: ", i+1);
scanf("%d", &userInput[i]);
}
write(fd[1], userInput, sizeof(userInput) + 1);
} else {
// Child
close(fd[1]);
int parentData[INPUT];
read(fd[0], parentData, sizeof(parentData));
for(int i = 0; i < INPUT; i++) {
printf("%d => %d", i+1, parentData[i]);
}
}
return 0;
}
当我 运行 使用 ./a.out 的程序时,我观察到以下行为。
Enter number 1: 1 => -4731629522 => 327663 => 2005319684 => 15 => 1
管道的实现方式是否有任何错误导致了此行为?
问题是文件描述符没有被 pipe-function 初始化。当达到 read-function 时,fd[0]
可能是一个无效的文件描述符。读取 0 个字节,写入标准输出的整数正是未初始化数组 parentData
中的整数。
只需添加:
pipe(fd);
同步是如何工作的?
当使用有效的文件描述符调用 read
函数时,内核 halts/blocks 处理并等待,直到其他进程将请求的字节数 (sizeof parentData
) 写入管道。然后内核从管道复制字节。这称为阻塞 IO。
注意:当写入进程stops/closes达到请求的字节数之前的文件描述符时,并不是所有的字节都被写入缓冲区。 read
的return值为读取的字节数。
还有非阻塞IO。进程可以在等待数据的同时做其他事情。它通常是用一个线程实现的,它从 filedescriptor/socket(network IO) 读取(阻塞 IO)并在完成时设置一个标志。
我正在使用 fork() 创建一个子进程,在父进程中我输入 5 个整数并将其保存到一个数组中。然后将此数据写入管道。然后子进程将从饼中读取数据并将其打印到屏幕上。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#define INPUT 5
int main() {
int fd[2];
pid_t childprocess;
if((childprocess = fork()) < 0) {
perror("Cannot fork child");
}
if(childprocess > 0) {
// Parent
int userInput[INPUT];
close(fd[0]);
for(int i = 0; i < INPUT; i++) {
printf("Enter number %d: ", i+1);
scanf("%d", &userInput[i]);
}
write(fd[1], userInput, sizeof(userInput) + 1);
} else {
// Child
close(fd[1]);
int parentData[INPUT];
read(fd[0], parentData, sizeof(parentData));
for(int i = 0; i < INPUT; i++) {
printf("%d => %d", i+1, parentData[i]);
}
}
return 0;
}
当我 运行 使用 ./a.out 的程序时,我观察到以下行为。
Enter number 1: 1 => -4731629522 => 327663 => 2005319684 => 15 => 1
管道的实现方式是否有任何错误导致了此行为?
问题是文件描述符没有被 pipe-function 初始化。当达到 read-function 时,fd[0]
可能是一个无效的文件描述符。读取 0 个字节,写入标准输出的整数正是未初始化数组 parentData
中的整数。
只需添加:
pipe(fd);
同步是如何工作的?
当使用有效的文件描述符调用 read
函数时,内核 halts/blocks 处理并等待,直到其他进程将请求的字节数 (sizeof parentData
) 写入管道。然后内核从管道复制字节。这称为阻塞 IO。
注意:当写入进程stops/closes达到请求的字节数之前的文件描述符时,并不是所有的字节都被写入缓冲区。 read
的return值为读取的字节数。
还有非阻塞IO。进程可以在等待数据的同时做其他事情。它通常是用一个线程实现的,它从 filedescriptor/socket(network IO) 读取(阻塞 IO)并在完成时设置一个标志。