【发布时间】:2014-06-02 04:14:11
【问题描述】:
我在使用 C 中的管道时遇到严重问题。我应该从命令行接收参数(例如:./myprogram 123 45 67),一次将一个字符读入缓冲区,发送字符给子进程进行统计,然后返回给父进程读取的字符总数。我的代码如下(注意:cmets 是我应该做的):
// Characters from command line arguments are sent to child process
// from parent process one at a time through pipe.
// Child process counts number of characters sent through pipe.
// Child process returns number of characters counted to parent process.
// Parent process prints number of characters counted by child process.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
static int toChild[2];
static int fromChild[2];
static char buffer;
int main(int argc, char **argv)
{
int status;
int nChars = 0;
pid_t pid;
pipe(toChild);
pipe(fromChild);
if ((pid = fork()) == -1) {
printf("fork error %d\n", pid);
return -1;
}
else if (pid == 0) {
close(toChild[1]);
close(fromChild[0]);
// Receive characters from parent process via pipe
// one at a time, and count them.
int count = 0;
printf("child about to read\n");
while(read(toChild[0], &buffer, 1)){
count++;
}
// Return number of characters counted to parent process.
write(fromChild[1], &count, sizeof(count));
close(toChild[0]);
close(fromChild[1]);
printf("child exits\n");
}
else {
close(toChild[0]);
close(fromChild[1]);
// -- running in parent process --
printf("CS201 - Assignment 3 - Chris Gavette\n");
write(toChild[1], &argv[1], 1);
// Send characters from command line arguments starting with
// argv[1] one at a time through pipe to child process.
read(fromChild[0], &nChars, 1);
// Wait for child process to return. Reap child process.
// Receive number of characters counted via the value
// returned when the child process is reaped.
close(toChild[1]);
close(fromChild[0]);
waitpid(pid, &status, 0);
printf("child counted %d chars\n", nChars);
printf("parent exits\n");
return 0;
}
}
即使我关闭了两个管道的两端,子进程似乎也挂起。
【问题讨论】:
-
您有两个
fork调用。你知道的,对吧?第二个盲目地覆盖从第一个返回的 pid。取出第一个。然后考虑您正在执行的所有读/写调用,并问自己来回发送的内容有多大。例如:write(toChild[1], &count, 1)。嗯,count是int;为什么你只发送一个字节而不是sizeof(count)?而且您的子循环退出条件充其量是不确定的。最后,以防您没有意识到;您应该为此使用 两个 管道描述符对;一个都没有。 -
啊哈,谢谢。这解决了两次调用的问题。
-
我发现在发布这个问题后一两分钟我需要两个文件描述符。我觉得很愚蠢,因为这应该很明显。谢谢!