Объяснение программы
Программы порождают n дочерних процессов, которые ставятся на паузу сразу после создания.После этого эти дочерние процессы по очереди общаются с родительским процессом по каналам.
Они говорят в течение фиксированного периода времени (например, должны говорить в общей сложности 20 раз, но останавливаются, когда они говорят 7несколько раз подряд и переходите к следующему процессу)
Выполнение программы
- Форкировка всех дочерних элементов
- Приостановка их сразу после их создания
- Разбудить их, отправив сигнал
- Дочерняя запись (в течение фиксированного периода времени) в родительский канал по каналу, а затем остановиться сразу после отправки сигнала родительскому / родительскому элементу чтения содержимого канала и записи в STDOUT * 1016.*
- Когда родительский приемник меняет канал, чтобы прочитать другого потомка, и сигнал пробуждает следующего потомка
Проблема
Проблема, с которой я сталкиваюсь, заключается в том, что когда пришло времячтобы перейти к следующему процессу, чтобы прослушать его, я не получаю ничего из канала следующего потомка, даже если я пишу в конец записи канала в дочернем процессе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
}
}