Поведение функции чтения, когда ребенок получает сигнал Sigstop - PullRequest
0 голосов
/ 03 января 2019

Объяснение программы

Программы порождают n дочерних процессов, которые ставятся на паузу сразу после создания.После этого эти дочерние процессы по очереди общаются с родительским процессом по каналам.

Они говорят в течение фиксированного периода времени (например, должны говорить в общей сложности 20 раз, но останавливаются, когда они говорят 7несколько раз подряд и переходите к следующему процессу)

Выполнение программы

  1. Форкировка всех дочерних элементов
  2. Приостановка их сразу после их создания
  3. Разбудить их, отправив сигнал
  4. Дочерняя запись (в течение фиксированного периода времени) в родительский канал по каналу, а затем остановиться сразу после отправки сигнала родительскому / родительскому элементу чтения содержимого канала и записи в STDOUT * 1016.*
  5. Когда родительский приемник меняет канал, чтобы прочитать другого потомка, и сигнал пробуждает следующего потомка

Проблема

Проблема, с которой я сталкиваюсь, заключается в том, что когда пришло времячтобы перейти к следующему процессу, чтобы прослушать его, я не получаю ничего из канала следующего потомка, даже если я пишу в конец записи канала в дочернем процессеs.Есть ли что-то, чего мне не хватает в SIGSTOP и SIGCONT при чтении.

Примечание: я прочитал документы

Программа

#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, wpid;
int nb_args,  read_return;

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

volatile sig_atomic_t status = 0;
volatile sig_atomic_t compteur = 0;

int main(int argc, char *argv[]){   
    write(STDERR_FILENO, "** Begining the program\n", 24); // debug
    nb_args = argc - 1; 
    if (nb_args >= 1 ){
        // Variable initialisation
        child_pids= malloc(nb_args * sizeof(pid_t)); 

        // String for sprintf
        char sstr[40]; 
        char rstr[40];
        char pidstr[23];
        char strichild[16];
        char strloopchild[10];

        // Initializing all the pipes for the processes
        int p[2 * nb_args];  

        // getting the pid of the parent process
        ppid = getpid();
        sprintf(pidstr, "Pid of parent is : %d\n", ppid);
        write(STDERR_FILENO, pidstr, 23); // debug

        int i, j, stop_val;

        //Initializing all pipes
        write(STDERR_FILENO, "**Init pipes\n", 13); // debug
        for (i = 0; i < nb_args; i++){
            if (pipe(&p[2*i]) == -1){
                perror("Error : pipe failed");
                _exit(EXIT_FAILURE);
            }
        }
        write(STDERR_FILENO, "**end init pipes\n", 17); // debug
        write(STDERR_FILENO, "**Begin fork\n", 15); // debug 
        for (i = 0; i <  nb_args; i ++){
            switch( n = fork()){
            case -1:
                perror("Error : fork failed");
                _exit(EXIT_FAILURE);
            case 0:
                /* CHILD */
                sprintf(strichild, "**In child n%d\n", i); // debug
                write(STDERR_FILENO, strichild, strlen(strichild)); // debug
                if (0 == (stop_val = atoi(argv[i+1]))){
                    perror("atoi failed");
                    _exit(EXIT_FAILURE);
                }
                sprintf(strichild, "stop_val is : %d\n", stop_val); // debug
                write(STDERR_FILENO, strichild, strlen(strichild)); // debug
                close(p[i*2]);
                for (j = 1; j <= 20 ; j++){
                    sprintf(strloopchild, "loop : %d\n", j); // debug
                    write(STDERR_FILENO, strloopchild , strlen(strloopchild)); // debug
                    if (j % stop_val == 0){
                        write(STDERR_FILENO, "I am  paused\n", 15); // debug
                        if ( kill(ppid, SIGUSR1) == -1){
                            write(STDERR_FILENO, "Could not kill\n",15); // debug
                        }
                        write(STDERR_FILENO, "Sent a sigusr1\n",15); // debug
                        kill(getpid(), SIGSTOP);

                    } 
                    write(STDERR_FILENO, "In child : ",11);  
                    sprintf(sstr, "J ecris sur l'entree %d du pipe\n", i*2+1);  
                    write(STDERR_FILENO, sstr, strlen(sstr));
                    sprintf(sstr, "Je suis le proc %d : message %d\n", getpid(), j);
                    write(STDERR_FILENO, sstr, 40); // debug
                    write(p[i * 2 + 1], sstr, 40);
                    sleep(1);

                }   
                close(p[i*2+1]);
                write(STDERR_FILENO, "**Exiting the child\n", 20); // debug
                _exit(EXIT_SUCCESS);

            default:
                /* PARENT - process scheduling */
                write(STDERR_FILENO, "**Parent - puting to sleep childs\n", 34); // debug 
                child_pids[i] = n;
                kill(n, SIGSTOP);
                // Setting up the signal
                signal(SIGUSR1, parentsighandler); 
            } 
        }
        write(STDOUT_FILENO, "Debut de l'ordonnancement\n",26);
        char strpids[20];
        for (i = 0; i < nb_args; i++){
            sprintf(strpids, "id processus : %d\n", child_pids[i]);
            write(STDOUT_FILENO, strpids, 20);
        }
        char mystr[17];
        sprintf(mystr, "compteur : %d\n", compteur); // debug
        write(STDOUT_FILENO, mystr, 17); // debug  
        kill(child_pids[compteur], SIGCONT);
        while(1){
            if (read(p[2 * compteur], rstr, 40) > 0) {
                write(STDOUT_FILENO,"P : ",5);
                write(STDOUT_FILENO, rstr, 40);
                sprintf(mystr, "compt value: %d\n", compteur); // debug
                write(STDOUT_FILENO, mystr, 17); // debug 
            } else {
                write(STDERR_FILENO, "Erreur lecture\n", 15);
            } 
            sleep(1);
        }


    } else {
        perror("Error : Not enough args\n");
        _exit(EXIT_FAILURE);
    }   
    return 0;
}

void parentsighandler(int sig){
    if (sig == SIGUSR1){
        write(STDOUT_FILENO, "*************\n", 14);//debug
        write(STDOUT_FILENO, "P : going into sig handler\n", 28); // debug
        if (compteur == (nb_args - 1)){
            compteur = 0;   
        } else {
            compteur ++;
        }
        kill(child_pids[compteur], SIGCONT);

        char strst[19];
        sprintf(strst, "P : compteur : %d\n", compteur); // debug
        write(STDOUT_FILENO, strst, 19); // debug 
        write(STDOUT_FILENO, "*************\n", 14);//debug
    }
}
...