我的老师分配了一项工作,其中包括制作一个伪调度程序。我现在停留在最重要的部分。给我麻烦的那一行是最后的waitpid行。基本上,我希望父进程等待他所有的孩子,这就是为什么我这样做了。但是代码在那时冻结了。当我发表评论时,它一直运行到最后,但没有任何内容写入STDOUT。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <signal.h>

#define LOOP_SIZE 20;

/* SIG HANDLERS DEFINITION */
void parentsighandler(int);

/* GLOBAL VARIABLE DEFINITION */
pid_t n, ppid;
int nb_args, compteur;

// array of pid_t to send signals to child
pid_t  *child_pids;


int main(int argc, char *argv[]){
    if (argc - 1 >= 1 ){
        // Variable initialisation
        compteur = 0;
        nb_args = argc - 1;
        child_pids = malloc((argc - 1) * sizeof(pid_t));

        // String for sprintf
        char sstr[40];
        char rstr[40];


        // Initializing all the pipes for the processes
        int p[2 * (argc - 1)];

        // getting the pid of the parent process
        ppid = getpid();

        //Initializing all pipes
        int i, j, status, stop_val;
        for (i = 0; i < argc - 1; i++){
            if (pipe(&p[2*i]) == -1){
                perror("pipe failed");
                _exit(EXIT_FAILURE);
            }
        }

        for (i = 0; i < argc - 1; i ++){
            switch( n = fork()){
                case -1:
                    perror("fork failed");
                    _exit(EXIT_FAILURE);
                case 0:
                    /* CHILD */
                    if (0 == (stop_val = atoi(argv[i+1]))){
                        perror("atoi failed");
                        _exit(EXIT_FAILURE);
                    }
                    close(p[i*2]);
                    for (j = 0; j < 20 ; j++){
                        write(STDOUT_FILENO, "here\n", 5);
                        if (j % stop_val == 0){
                            kill(ppid, SIGUSR1);
                        }
                        sprintf(sstr, "Je suis le proc %d : message %d\n", getpid(), i);
                        write(p[i * 2 + 1], sstr, 40);
                    }
                    close(p[i*2+1]);
                    _exit(EXIT_SUCCESS);

                default:
                    /* PARENT - process scheduling */
                    child_pids[i] = n;
                    kill(n, SIGSTOP);
            }
        }
        write(STDOUT_FILENO, "Debut de l'ordonnancement\n",26);

        // Setting up the signal
        signal(SIGUSR1, parentsighandler);

        write(STDOUT_FILENO, "before wait\n",12);
        // The parent as to wait for all child to finish
        for (i = 0; i < argc - 1; i ++){
        //  write(STDOUT_FILENO, "beit\n",12);
            printf("value of pid n%d is %d\n", i, child_pids[i]);
    //      waitpid(child_pids[i], &status, 0);
        //  close(p[i * 2 + 1]); // closing the write end of the pipe
        }

        write(STDOUT_FILENO, "cefore main\n",12);
        char mystr[15];
        sprintf(mystr, "compteur : %d\n", compteur);
        write(STDOUT_FILENO, mystr, 15);
        while(1){
            write(STDOUT_FILENO, "refore main\n",12);
            kill(child_pids[compteur], SIGCONT);
            write(STDOUT_FILENO, "jefore main\n",12);
            while(read(p[2 * compteur], rstr, 40) > 0){
                write(STDOUT_FILENO, rstr, 40);
            }
        }
    } else {
        perror("Not enough args\n");
        _exit(EXIT_FAILURE);
    }
    return 0;
}

void parentsighandler(int sig){
    if (sig == SIGUSR1){
        write(STDOUT_FILENO, "passe dans sig handler\n", 23);
        kill(child_pids[compteur], SIGSTOP);
        if (compteur == nb_args){
            compteur = 0;
        } else {
            compteur ++;
        }
    }
}

最佳答案

为何父母(似乎)停在指令上:

waitpid(child_pids[i], &status, 0);


因为孩子要杀死父母,所以在父母设置信号处理程序之前

关于c - 是否可以多次调用waitpid? [UNIX] [C],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53997676/

10-13 03:32