linux - exec' d程序没有终止

时间:2016-12-02 19:16:51

标签: c linux

我在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);
}

1 个答案:

答案 0 :(得分:0)

为了能够从管道中检测文件的结尾,您需要从没有编写器的空管道读取(没有打开写入描述符的进程)。

由于您的编写器(first_func())从不关闭其描述符并始终在永无止境的循环中写入内容,因此读者将等待某些数据或读取某些数据。

关闭非有用的描述符也要小心,如果没有,你可能会遇到管道的一些问题,例如有一个进程是读者和编写者,因此无法检测到文件的结尾......