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.
lamport.c:
//(c)2002 Tomasz Lubinski //www.algorytm.org //algorytm Lamport'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> int n; //definicja funkcji max int max(int a, int b) { if (a>b) return a; else return b; } void usun_pamiec() { int shmid,key; for (key=1; key<=n; key++) { shmid=shmget(100+key, 4, IPC_CREAT); shmctl(shmid, IPC_RMID, NULL); } for (key=1; key<=n; key++) { shmid=shmget(200+key, 4, IPC_CREAT); shmctl(shmid, IPC_RMID, NULL); } exit(0); } int main() { int* choosing[100]; int* num[100]; int shmid,key; struct shmid_ds buf; printf("Podaj dla ilu procesow chcesz przetestowac algorytm (max. 99)\n"); scanf("%d", &n); //zainicjowanie zmiennych wspoldzielonych for (key=1; key<=n; key++) { shmid=shmget(100+key, 4, IPC_CREAT); shmctl(shmid, IPC_STAT, &buf); buf.shm_perm.mode=0666; shmctl(shmid, IPC_SET, &buf); choosing[key]=shmat(shmid, NULL, SHM_RND); *choosing[key]=0; } for (key=1; key<=n; key++) { shmid=shmget(200+key, 4, IPC_CREAT); shmctl(shmid, IPC_STAT, &buf); buf.shm_perm.mode=0666; shmctl(shmid, IPC_SET, &buf); num[key]=shmat(shmid, NULL, SHM_RND); *num[key]=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"); //uruchomienie n procesow potomnych, ktore beda dzialaly wspolbieznie for (key=1; key<=n; key++) { if (fork()==0) { int test,k,mine,other,temp,pid; pid=key; //kazdy proces potomny otrzymuje wlasny numer pid //algorytm Lamport'a while(1) { printf("P%d jest poza sekcja krytyczna\n", pid); sleep(random()%15); printf("P%d chce wejsc do sekcji krytycznej\n", pid); *choosing[pid]=1; for (k=1; k<=n; k++) if (k!=pid) { temp=*num[k]; mine=max(mine, temp); } mine++; *num[pid]=mine; *choosing[pid]=0; for (k=1; k<=n; k++) if (k!=pid) { do test=*choosing[k]; while(test!=0); do other=*num[k]; while(!(other==0||mine<other||(mine==other&&pid<k))); } printf("\t\t\t\tP%d jest w sekcji krytycznej\n", pid); sleep(random()%10); *num[pid]=0; } } } wait(NULL); }