将 child 的标准输出通过管道传输到 c 中另一个 child 的标准输入
pipe stdout of a child to stdin of another child in c
这就是我想要做的:一个 parent 进程创建两个 child 进程,然后将一个进程的标准输出通过管道传输到另一个进程的标准输入。然后 parent 等待 5 秒并杀死第一个 child.
我是这样处理的:首先我创建了一个管道。然后 fork 创建第一个 child (代码中的 gen)和 dup2 以复制管道对 stdout 的写入。第二个 child 的另一个分支(在代码中称为 cons),dup2 将读取结束复制到标准输入。缺点只是打印数据。 Parent 将 SIGTERM 发送到第一个 child,第二个 child 读取到 EOF,因此它自行关闭。
只打印了我的错误输出(此处用于调试)。 Gen 生成两个随机数,但 cons 中的循环不会被执行。所以我想 cons 的 stdin 上没有任何内容。
我咨询了 Google 并遵循了这个 How do I chain stdout in one child process to stdin in another child in C?,但没能弄清楚我搞砸了什么。将不胜感激任何帮助。谢谢
编译:gcc -std=c99 -Wall -Werror main.c -o main
在 Bash 上 Windows 10
代码:
#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;
}
默认情况下标准输出是缓冲的,因此您的 gen child 仅将输出排队等待稍后发送。所以你必须fflush
它来强制你的消息被立即传递:
...
printf("gen %d %d\n", a, b);
fprintf(stderr, "err, gen %d %d\n", a, b);
fflush(stdout); // <= force immediate send
sleep(1);
...
这就是我想要做的:一个 parent 进程创建两个 child 进程,然后将一个进程的标准输出通过管道传输到另一个进程的标准输入。然后 parent 等待 5 秒并杀死第一个 child.
我是这样处理的:首先我创建了一个管道。然后 fork 创建第一个 child (代码中的 gen)和 dup2 以复制管道对 stdout 的写入。第二个 child 的另一个分支(在代码中称为 cons),dup2 将读取结束复制到标准输入。缺点只是打印数据。 Parent 将 SIGTERM 发送到第一个 child,第二个 child 读取到 EOF,因此它自行关闭。
只打印了我的错误输出(此处用于调试)。 Gen 生成两个随机数,但 cons 中的循环不会被执行。所以我想 cons 的 stdin 上没有任何内容。 我咨询了 Google 并遵循了这个 How do I chain stdout in one child process to stdin in another child in C?,但没能弄清楚我搞砸了什么。将不胜感激任何帮助。谢谢
编译:gcc -std=c99 -Wall -Werror main.c -o main
在 Bash 上 Windows 10
代码:
#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;
}
默认情况下标准输出是缓冲的,因此您的 gen child 仅将输出排队等待稍后发送。所以你必须fflush
它来强制你的消息被立即传递:
...
printf("gen %d %d\n", a, b);
fprintf(stderr, "err, gen %d %d\n", a, b);
fflush(stdout); // <= force immediate send
sleep(1);
...