我在Linux上用C语言编写程序,必须分叉2个孩子。
第一个孩子将通过管道将两个随机数发送给第二个孩子。它将侦听SIGUSR1信号,然后终止。
第二个子节点将(dup2)管道输入复制为STDIN,将文件 fp 复制为STDOUT。然后它将执行程序,该程序将根据其输入和结束打印出一些数据。
我的问题是,execl程序永远不会终止,我不知道为什么。任何帮助或提示将不胜感激。
main.c(父母):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
const int BUFFER_SIZE = 30;
int pipefd[2] = {0,0};
int parent_pid = 0;
int first_pid = 0;
int second_pid = 0;
int sleep_time = 5;
int debug = 0;
FILE *fp;
void parent_func() {
int wstatus = 0;
sleep(sleep_time);
kill(first_pid, SIGUSR1);
wait(&wstatus);
waitpid(second_pid, &wstatus, 0);
}
static void sigusr1_handler(int sig) {
if (sig == SIGUSR1) {
fputs("TERMINATED", stderr);
close(pipefd[1]);
exit(0);
}
}
void first_func() {
struct sigaction act;
char buffer[BUFFER_SIZE];
close(pipefd[0]);
memset(&act, '\0', sizeof(act)); // clear the sigaction struct
act.sa_handler = &sigusr1_handler; // sets function to run on signal
if (sigaction(SIGUSR1, &act, NULL) < 0) { // assign sigaction
fputs("cannot assign sigaction - exiting...", stderr);
exit(1);
}
while (1) {
sprintf(buffer, "%d %d\n", rand(), rand());
write(pipefd[1], buffer, strlen(buffer));
puts(buffer);
sleep(1);
}
}
void second_func() {
close(pipefd[1]);
fp = fopen("out.txt", "w");
char buf[30];
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]);
//dup2(fileno(fp), STDOUT_FILENO);
execl("./test", "", NULL);
perror("Error");
}
int main(int argc, char *argv[]) {
int fork_val = 0;
parent_pid = getpid();
if (pipe(pipefd)) {
fputs("cannot create pipe - exiting...", stderr);
return 1;
}
if (debug) {
sleep_time *= 10;
}
if ((fork_val = fork()) == -1) {
fputs("cannot fork process - exiting...", stderr);
return 1;
} else if (fork_val == 0) {
first_func();
} else {
first_pid = fork_val;
if ((fork_val = fork()) == -1) {
fputs("cannot fork process - exiting...", stderr);
return 1;
} else if (fork_val == 0) {
second_func();
} else {
second_pid = fork_val;
parent_func();
}
}
fclose(fp);
exit(0);
}
test.c(execl&#39; d文件):
#include "nd.h"
#include "nsd.h"
#include <stdio.h>
#include <stdlib.h>
int main() {
int num1 = 0;
int num2 = 0;
char buffer[100];
while (fgets(buffer, 100, stdin) != NULL) {
if (sscanf(buffer, "%d %d", &num1, &num2) == 2) {
(num1 < 0) ? num1 = (num1 * -1) : num1;
(num2 < 0) ? num2 = (num2 * -1) : num2;
if (num1 == 1 || num2 == 1) {
puts("1");
} else if (num1 == num2) {
if (nd(num1) == 1) {
puts("prime");
} else {
printf("%d\n", num1);
}
} else if (nd(num1) == 1 && nd(num2) == 1) {
puts("prime");
} else {
printf("%d\n", nsd(num1, num2));
}
} else {
fputs("error\n", stderr);
}
}
fputs("DONE", stderr);
exit(0);
}
答案 0 :(得分:0)
为了能够从管道中检测文件的结尾,您需要从没有编写器的空管道读取(没有打开写入描述符的进程)。
由于您的编写器(first_func()
)从不关闭其描述符并始终在永无止境的循环中写入内容,因此读者将等待某些数据或读取某些数据。
关闭非有用的描述符也要小心,如果没有,你可能会遇到管道的一些问题,例如有一个进程是读者和编写者,因此无法检测到文件的结尾......