【发布时间】:2019-10-28 17:08:55
【问题描述】:
我是 linux 编程的新手。我正在尝试生成两个子进程并通过管道连接它们。生成子进程应该生成随机数,而另一个子进程应该运行一个二进制文件,该二进制文件接受这两个数字并找到它们的最大公约数。二进制文件已经很好地与标准输入一起工作,所以我试图将它重定向到读取管道的末端。同样,我通过将标准输出连接到管道的写入端来生成进程。
但我认为我没有做好将它们连接在一起的工作,因为没有输出。任何帮助将不胜感激!
我没有在网上找到很多资料,所以建议这些资料也会有很大帮助。谢谢。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#define exec_path "nsd"
void create_pipe(int *proc_pipe);
int create_proc();
void sig_handler(int sig);
int main() {
int proc_pipe[2];
pid_t gen_proc;
pid_t nsd_proc;
int proc_stat;
create_pipe(proc_pipe);
gen_proc = create_proc();
if (gen_proc == 0) {
// child exec
struct sigaction act;
act.sa_handler = &sig_handler;
close(proc_pipe[0]);
dup2(proc_pipe[1], 1);
close(proc_pipe[1]);
while (1) {
printf("%d %d\n", rand() % 4096, rand() % 4096);
sleep(1);
if (sigaction(SIGTERM, &act, NULL) == -1) exit(2);
}
} else {
nsd_proc = create_proc();
if (nsd_proc == 0) {
// child exec
close(proc_pipe[1]);
dup2(proc_pipe[0], 0);
close(proc_pipe[0]);
execl(exec_path, "nsd", (char *) NULL);
} else {
close(proc_pipe[0]);
close(proc_pipe[1]);
sleep(5);
kill(gen_proc, SIGTERM);
wait(&proc_stat);
if (proc_stat != 0) {
perror("ERROR");
return 1;
} else {
printf("OK\n");
return 0;
}
}
}
}
void sig_handler(int sig) {
if (sig == SIGTERM) {
perror("GEN TERMINATED");
exit(0);
}
}
pid_t create_proc() {
pid_t pid = fork();
if (pid == -1) {
perror("error forking new process");
exit(2);
}
return pid;
}
void create_pipe(int *proc_pipe) {
if (pipe(proc_pipe) == -1) {
perror("failed to create pipe");
exit(2);
}
}
【问题讨论】:
-
perror消息通常不以换行符结尾,因为“首先(如果 s 不是 NULL 并且 *s 不是空字节 ('\0')),参数字符串 s 是打印,后跟一个冒号和一个空格。” (man7.org/linux/man-pages/man3/perror.3.html) -
gen_proc = create_proc(); nsd_proc = create_proc();:这两行创建了 3 个进程。第二行由父级执行一次,子级在第一行创建一次。 -
“nsd”是当前目录中的可执行文件吗?
-
@user253751 是的,它在当前目录中
-
@IngoLeonhardt 好吧,我移动了父分支中的第二个分叉以避免不必要的分叉。现在编辑代码以供进一步检查。
nsd_proc仍然没有输出。