我试图用C语言编写一个简单的程序,其中一些内容通过管道传递给子进程两次,每次使用不同的值:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#define READ 0
#define WRITE 1
int main(){
int myPipe[2];
if (pipe(myPipe) < 0) {
fprintf(stderr,"Pipe Error!");
return -1;
}
pid_t pid = fork();
if (pid < 0)
perror("Error forking!");
else if(pid > 0){
// Master
char var[4];
// Sends the first value.
sprintf(var, "foo");
close(myPipe[READ]);
write(myPipe[WRITE], var, sizeof(var));
close(myPipe[WRITE]);
// Sends the second value.
sprintf(var, "bar");
close(myPipe[READ]);
write(myPipe[WRITE], var, sizeof(var));
close(myPipe[WRITE]);
wait(NULL);
return 0;
}
else if (pid == 0){ // Child
char received[4];
// Reads the first value.
close(myPipe[WRITE]);
read(myPipe[READ], received, sizeof(received));
close(myPipe[READ]);
printf("I have received the following value: %s\n", received);
// Reads the second value.
close(myPipe[WRITE]);
read(myPipe[READ], received, sizeof(received));
close(myPipe[READ]);
printf("I have received the following value: %s\n", received);
return 0;
}
}
不过,输出似乎不是预期的,因为变量
received
从不改变其值:I have received the following value: foo
I have received the following value: foo
…当所需输出为:
I have received the following value: foo
I have received the following value: bar
我不明白为什么会发生这种情况,因为我认为-可能是错误的-管道在每次使用时都会被覆盖,就像您可以执行的那样:
int i = 0;
printf("%i\n", i);
i = 4;
printf("%i", i);
……它将返回:
0
4
为什么这种现象不发生在管道中?
最佳答案
为什么这种现象不发生在管道中?
你打电话的次数比你应该打的多。
父进程在第二次写入之前关闭管道的写入端(即:“bar”)。子进程在第二次读取之前关闭管道的读取端。因此,子进程中的第二次读取实际上没有从管道中读取任何内容,因为传递给close()
的文件描述符无效。注意,父进程中的第二个read()
也没有成功,原因相同。
此外,已关闭的管道端将再次关闭:父级中的读取端和子级中的写入端。
通过删除那些对write()
不方便的调用,代码将产生您所期望的结果:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#define READ 0
#define WRITE 1
int main(){
int myPipe[2];
if (pipe(myPipe) < 0) {
fprintf(stderr,"Pipe Error!");
return -1;
}
pid_t pid = fork();
if (pid < 0)
perror("Error forking!");
else if(pid > 0){
// Master
char var[4];
// Sends the first value.
sprintf(var, "foo");
close(myPipe[READ]);
write(myPipe[WRITE], var, sizeof(var));
// Sends the second value.
sprintf(var, "bar");
write(myPipe[WRITE], var, sizeof(var));
close(myPipe[WRITE]);
wait(NULL);
return 0;
}
else if (pid == 0){ // Child
char received[4];
// Reads the first value.
close(myPipe[WRITE]);
read(myPipe[READ], received, sizeof(received));
printf("I have received the following value: %s\n", received);
// Reads the second value.
read(myPipe[READ], received, sizeof(received));
printf("I have received the following value: %s\n", received);
return 0;
}
return 0;
}
也就是说,输出是:
I have received the following value: foo
I have received the following value: bar