Nadesłany przez Tomasz Lubiński, 26 lipca 2005 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
deker.c:
//(c)2002 Tomasz Lubinski //www.algorytm.org //algorytm Dekker'a - problem wzajemnego wykluczania #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <signal.h> void usun_pamiec() { int shmid; shmid=shmget(101, 4, IPC_CREAT); shmctl(shmid, IPC_RMID, NULL); shmid=shmget(102, 4, IPC_CREAT); shmctl(shmid, IPC_RMID, NULL); shmid=shmget(103, 4, IPC_CREAT); shmctl(shmid, IPC_RMID, NULL); printf("Koniec\n"); exit(0); } int main() { int* favoredprocess; int* p1wantstoenter; int* p2wantstoenter; //zainicjowanie zmiennych wspoldzielonych int shmid; struct shmid_ds buf; shmid=shmget(101, 4, IPC_CREAT); shmctl(shmid, IPC_STAT, &buf); buf.shm_perm.mode=0666; shmctl(shmid, IPC_SET, &buf); favoredprocess=shmat(shmid, NULL, SHM_RND); *favoredprocess=1; shmid=shmget(102, 4, IPC_CREAT); shmctl(shmid, IPC_STAT, &buf); buf.shm_perm.mode=0666; shmctl(shmid, IPC_SET, &buf); p1wantstoenter=(int*)shmat(shmid, NULL, SHM_RND); *p1wantstoenter=0; shmid=shmget(103, 4, IPC_CREAT); shmctl(shmid, IPC_STAT, &buf); buf.shm_perm.mode=0666; shmctl(shmid, IPC_SET, &buf); p2wantstoenter=(int*)shmat(shmid, NULL, SHM_RND); *p2wantstoenter=0; //po zakonczeniu wykonywania progamu pamiec wspoldzielona nalezy usunac. //po nacisnieciu klawiszy ctrl+c sygnal SIGINT jest przechwytywany i //uruchamiana jest funkcja usun_pamiec signal(SIGINT, usun_pamiec); printf("Program nalezy przerwac wciskajac ctrl+c\n\n"); //algorytm Dekker'a if (fork()==0) { //proces 1 while(1) { printf("P1 jest poza sekcja krytyczna\n"); sleep(random()%10); printf("P1 chce wejsc do sekcji krytycznej\n"); *p1wantstoenter=1; while (*p2wantstoenter==1) if (*favoredprocess==2) { *p1wantstoenter=0; while (*favoredprocess==2) ; *p1wantstoenter=1; } printf("\t\t\tP1 jest w sekcji krytycznej\n"); sleep(random()%10); *favoredprocess=2; *p1wantstoenter=0; } } else { //proces 2 while(1) { printf("P2 jest poza sekcja krytyczna\n"); sleep(random()%10); printf("P2 chce wejsc do sekcji krytycznej\n"); *p2wantstoenter=1; while (*p1wantstoenter==1) if (*favoredprocess==1) { *p2wantstoenter=0; while (*favoredprocess==1) ; *p2wantstoenter=1; } printf("\t\t\tP2 jest w sekcji krytycznej\n"); sleep(random()%10); *favoredprocess=1; *p2wantstoenter=0; } } }