我对管道和并发性有点新意,并且对这个问题感到沮丧数小时。我正在努力理解为什么这个write
操作一直在我的管道上失败。我试图让子进程通过父进程将接收的管道写入数据。我目前的代码是:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 4096
int main() {
pid_t status;
int fd[2]; //The array of file descriptors
if (pipe(fd) == -1) {
printf("Error piping");
}
status = fork(); //Begin the fork process
switch (status) {
case -1:
perror("Error forking");
break;
case 0:
//Child process
close(fd[0]); //Only send data
char some_string[15] = "hi there";
if (write(fd[1], some_string, MAXSIZE) == -1) {
printf("Error writing to the pipe");
}
close(fd[1]); //Close write end
exit(1);
default:
close(fd[1]); //Only receive data
char readed[500] = "";
while(read(fd[0], readed, MAXSIZE) != 0) {
printf("read this %s\n", readed);
}
printf("Done reading");
close(fd[0]);
break;
}
return 1;
}
但是,我经常收到消息“写入管道时出错”,这意味着write
操作在子进程中失败了。另一个有趣的事情是,如果我将some_string
更改为字符串文字,则此代码可以正常工作,但它永远不会终止,而父进程中的read
操作将从{{1}读取}!我不明白为什么会发生这种情况,父母执行时我们有一个僵尸孩子,因此管道“死了”?或许父进程终止,我们有一个孤儿?我怎样才能避免这种情况,以及如何解释字符串文字中的奇怪行为呢?任何见解?
答案 0 :(得分:2)
您告诉write()
从数组的超出范围读取数据,并允许read()
将读取的数据写入数组的超出范围。这非常糟糕。
仅写入有效数据并限制读取的长度,以免导致超出范围的访问。
试试这个:
#include <unistd.h>
#include <sys/types.h> /* add this to use pid_t */
#include <sys/wait.h> /* add this to use wait() */
#include <stdio.h>
#include <stdlib.h>
/* remove unused MAXSIZE */
int main() {
pid_t status;
int fd[2]; //The array of file descriptors
int st; /* variable for receiving the status */
if (pipe(fd) == -1) {
printf("Error piping");
return 1; /* return 1 when the execution failed */
}
status = fork(); //Begin the fork process
switch (status) {
case -1:
perror("Error forking");
return 1; /* return 1 when the execution failed */
break;
case 0:
//Child process
close(fd[0]); //Only send data
char some_string[15] = "hi there";
if (write(fd[1], some_string, sizeof(some_string)) == -1) {
printf("Error writing to the pipe");
}
close(fd[1]); //Close write end
exit(0); /* return 0 if the execution finished successfully */
default:
close(fd[1]); //Only receive data
char readed[500] = "";
while(read(fd[0], readed, sizeof(readed) - 1) != 0) { /* -1 for reserving space for terminating null-character */
printf("read this %s\n", readed);
}
printf("Done reading");
close(fd[0]);
wait(&st); /* wait for the child process to exit and release the data of the process */
break;
}
return 0; /* return 0 if the execution finished successfully */
}