这就是我尝试做的事情:父进程创建两个子进程,然后将stdout的一个stdout传递给另一个进程的stdin。然后父母等待5秒并杀死第一个孩子。
这就是我接近它的方式:首先我创建一个管道。然后fork来创建第一个子节点(gen代码)和dup2来复制管道写入stdout。第二个子句的另一个fork(在代码中称为cons),dup2将读取结束复制到stdin。缺点只是打印数据。父母将SIGTERM发送给第一个孩子,第二个孩子读到EOF,所以它关闭了它自己。
只打印我的错误输出(此处用于调试)。 Gen生成两个随机数,但cons的循环不会被执行。因此,我认为缺点是没有任何缺陷。 我咨询了谷歌,并遵循了这个How do I chain stdout in one child process to stdin in another child in C?,但没有设法弄清楚我搞砸了什么。非常感谢任何帮助。感谢
编译:在Windows 10中的Bash上编译gcc -std=c99 -Wall -Werror main.c -o main
代码:
#define _POSIX_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <signal.h>
#define READ_END 0
#define WRITE_END 1
#define BUF_SIZE 10
int main(int argc, char* argv[])
{
pid_t gen, cons;
int fd[2];
if (pipe(fd) < 0) {
// pipe error
exit(1);
}
gen = fork();
if (gen < 0) {
// fork error
close(fd[READ_END]);
close(fd[WRITE_END]);
exit(2);
} else if (gen == 0) {
// gen child
close(fd[READ_END]);
time_t t;
srand((unsigned)time(&t));
dup2(fd[WRITE_END], STDOUT_FILENO);
close(fd[WRITE_END]);
while(1) {
int a = rand() % 1000;
int b = rand() % 1000;
printf("gen %d %d\n", a, b);
fprintf(stderr, "err, gen %d %d\n", a, b);
sleep(1);
}
}
else {
cons = fork();
if (cons < 0) {
// fork error
close(fd[READ_END]);
close(fd[WRITE_END]);
kill(gen, SIGKILL);
exit(2);
} else if (cons == 0) {
// cons child
close(fd[WRITE_END]);
dup2(fd[READ_END], STDIN_FILENO);
close(fd[READ_END]);
char line[BUF_SIZE];
while (fgets(line, sizeof(line), stdin)) {
printf("cons received: %s\n", line);
fprintf(stderr, "cons lives!\n");
}
} else {
// parent
close(fd[READ_END]);
close(fd[WRITE_END]);
sleep(5);
kill(gen, SIGTERM);
}
}
return 0;
}
答案 0 :(得分:1)
默认情况下,标准输出是缓冲的,因此您的gen子队列只会将输出排队等待以后发送。因此,您必须fflush
强制传递您的信息:
...
printf("gen %d %d\n", a, b);
fprintf(stderr, "err, gen %d %d\n", a, b);
fflush(stdout); // <= force immediate send
sleep(1);
...