我正在尝试编写一个包含两个进程的程序:
一个进程生成一些a + b问题并将其打印到stdout(如printf("%d %d\n", a, b)
),并通过stdin从另一个进程获得答案,并将答案记录到log.txt。当询问所有问题时,该过程将打印出“-1 -1”以指示问题的结束。
另一个进程通过stdin(如scanf("%d%d", &a, &b)
)接收a + b问题,并将答案打印到其stdout。当a = b = -1
进程退出时。
我正在使用两对管道来连接这两个进程。我使用dup2
将管道绑定到stdin和stdout。我的源代码如下所示:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
// Get a + b question through stdin, and print answer to stdout
void calc_a_plus_b() {
int a, b;
while (scanf("%d%d", &a, &b) > 0)
{
if (a == -1 && b == -1)
break;
printf("%d\n", a + b);
fflush(stdout);
}
}
// Ask a + b through stdout, and get answer through stdin
// Log answer to log.txt
void ask_a_plus_b() {
FILE* log = fopen("log.txt", "w");
int i, a, b, c;
for (i = 0; i < 3; i++) {
a = i; b = i + 1;
printf("%d %d\n", a, b);
fflush(stdout);
scanf("%d", &c);
fprintf(log, "%d\n", c);
}
printf("-1 -1\n");
fclose(log);
}
int main()
{
pid_t ask_pid, calc_pid, term_pid;
int ask_to_calc[2], calc_to_ask[2]; // Two pairs of pipe
int status;
// Create pipe
pipe(ask_to_calc); pipe(calc_to_ask);
// Create calculate process
calc_pid = fork();
if (calc_pid == 0) {
// Close useless pipe
close(ask_to_calc[1]);
close(calc_to_ask[0]);
// Bind pipe to stdin and stdout
dup2(ask_to_calc[0], 0);
dup2(calc_to_ask[1], 1);
close(ask_to_calc[0]);
close(calc_to_ask[1]);
calc_a_plus_b();
return 0;
}
// Create ask process
ask_pid = fork();
if (ask_pid == 0) {
// Close useless pipe
close(ask_to_calc[0]);
close(calc_to_ask[1]);
// Bind pipe to stdin and stdout
dup2(calc_to_ask[0], 0);
dup2(ask_to_calc[1], 1);
ask_a_plus_b();
return 0;
}
// Wait for children to exit
while ((term_pid = wait(&status)) > 0) {
if (WIFSTOPPED(status))
{
// If child stopped but hasn't exited, ignore
continue;
} else if (WIFSIGNALED(status)) {
// Child exited due to signal
printf("%s terminated due to signal %d\n", ask_pid == term_pid ? "ask" : "calc", WTERMSIG(status));
} else {
// Child exited normally
printf("%s terminated normally\n", ask_pid == term_pid ? "ask" : "calc");
}
}
return 0;
}
此代码正常运行,并打印出
calc terminated normally
ask terminated normally
从man 7 pipe
(http://man7.org/linux/man-pages/man7/pipe.7.html)我知道,当管道读取端的所有文件描述符都关闭,而另一个进程仍然尝试写入此管道时,将发生一个SIGPIPE 。所以我决定删除calc_a_plus_b
中的所有代码,看看会发生什么。
令人惊讶的是,SIGPIPE没有发生。该程序只打印出
calc terminated normally
之后程序被卡住了。我想这是因为printf
中的ask_a_plus_b
被屏蔽了。
我想我已经将所有文件描述符关闭到管道ask_to_calc
的读取端(我已将管道绑定到计算过程的stdin,但是进程已经退出,所以它的stdin也是关闭了吗?),那么为什么在询问过程试图写入管道时不会发生SIGPIPE?
答案 0 :(得分:0)
感谢@Art的评论。我忘了在父进程中关闭管道-_-&#34;
关闭父进程中的管道后,由于SIGPIPE,请求进程现在终止。