#include #include #include #include // SIGCONT = reçu par fil1 ou fils2 = acquittement du controleur // SIGUSR1 = reçu par le contrôleur = demande de fil1 // SIGUSR2 = reçu par le contrôleur = demande de fil2 // SIGINT = reçu par le controleur = fin de traitement d'un fils // SIGALRM = reçu par le controleur = fin du programme #define N 20 int pid1,pid2; // pid du fils int *tab; // adresse de la mémoire partagée int id_shm; // identifiant de mémoire partagée sigset_t ens; // ensemble de signaux void hasard(int pid, int *i, int *j) { *i = rand()%N; *j = rand()%N; //printf("[%d] choisit i=%d j=%d\n",pid,*i,*j); } void echanger(int *t, int i, int j) { int z; //printf("echange t[%d]=%d <-> t[%d]=%d \n",i,t[i],j,t[j]); z = t[i]; t[i] = t[j]; t[j] = z; } void init(int *t) { int i; for(i=0;itab[j]) // dans le désordre echanger(tab,i,j); kill(getppid(),SIGINT); // on envoi SIGINT (fini au contrôleur) } } pid2 = fork(); if(pid2 == 0) { int i,j; /* code du deuxième fils */ // attachement du segment de mémoire à l'adresse x tab = (int *)shmat(id_shm, NULL, 0); // changer les comportements associés à // SIGCONT act.sa_handler = handler_fils2_SIGCONT; sigfillset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGCONT,&act,NULL); while(1) { hasard(getpid(),&i,&j); kill(getppid(),SIGUSR2); // envoi SIGUSR2 au contrôleur sigfillset(&ens); sigdelset(&ens,SIGCONT); sigsuspend(&ens); // on attend l'arrivée de SIGCONT if(itab[j]) // dans le désordre echanger(tab,i,j); kill(getppid(),SIGINT); // on envoi SIGINT (fini au contrôleur) } } // code du père (contrôleur) // changer les comportements associés à // SIGUSR1, SIGUSR2, SIGALRM et SIGINT sigfillset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = handler_controleur_SIGUSR1; sigaction(SIGUSR1,&act,NULL); sigfillset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = handler_controleur_SIGUSR2; sigaction(SIGUSR2,&act,NULL); sigfillset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = handler_controleur_SIGALRM; sigaction(SIGALRM,&act,NULL); sigfillset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = handler_controleur_SIGINT; sigaction(SIGINT,&act,NULL); alarm(5); /* code du père */ while(1) { etat = 0; // recevoir un signal SIGUSR1, SIGUSR2 ou SIGALRM sigfillset(&ens); sigdelset(&ens,SIGUSR1); sigdelset(&ens,SIGUSR2); sigdelset(&ens,SIGALRM); sigsuspend(&ens); switch(etat) { case 1: // c'est pid1 qui demande //printf("[controleur] signal SIGUSR1 recu\n"); kill(pid1,SIGCONT); // on envoi un accusé-reception au premier fils //printf("[controleur] signal SIGUSR1 envoye\n"); sigfillset(&ens); sigdelset(&ens,SIGALRM); sigdelset(&ens,SIGINT); sigsuspend(&ens); // on attend un signal SIGINT ou SIGALRM //printf("[controleur] signal SIGUSR1 recu par le controleur\n"); break; case 2: // c'est pid2 qui demande //printf("[controleur] signal SIGUSR2 recu\n"); kill(pid2,SIGCONT); // on envoi un accusé-reception au premier fils // recevoir un signal //printf("[controleur] signal SIGUSR2 envoye\n"); sigfillset(&ens); sigdelset(&ens,SIGALRM); sigdelset(&ens,SIGINT); sigsuspend(&ens); // on attend un signal SIGINT ou SIGALRM //printf("[controleur] signal SIGUSR2 recu par le controleur\n"); break; } } }