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.
dijkstra.c:
//(c)2002 Tomasz Lubinski
//www.algorytm.org
//algorytm Dijkstry - 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;
void usun_pamiec()
{
int shmid,key;
shmid=shmget(100, 4, IPC_CREAT);
shmctl(shmid, IPC_RMID, NULL);
for (key=1; key<=n; key++)
{
shmid=shmget(100+key, 4, IPC_CREAT);
shmctl(shmid, IPC_RMID, NULL);
}
exit(0);
}
int main()
{
int* flag[100];
int* turn;
int shmid,key;
struct shmid_ds buf;
printf("Podaj dla ilu procesow chcesz przetestowac algorytm (max. 99)\n");
scanf("%d", &n);
//zainicjowanie zmiennych wspoldzielonych
shmid=shmget(100, 4, IPC_CREAT);
shmctl(shmid, IPC_STAT, &buf);
buf.shm_perm.mode=0666;
shmctl(shmid, IPC_SET, &buf);
turn=shmat(shmid, NULL, SHM_RND);
*turn=1;
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);
flag[key]=shmat(shmid, NULL, SHM_RND);
*flag[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,other,temp,pid;
pid=key; //kazdy proces potomny otrzymuje wlasny numer pid
//algorytm Dijsktry
while(1)
{
printf("P%d jest poza sekcja krytyczna\n", pid);
sleep(random()%15);
printf("P%d chce wejsc do sekcji krytycznej\n", pid);
L: *flag[pid]=1;
other=*turn;
while (other!=pid)
{
test=*flag[other];
if (test==0) *turn=pid;
other=*turn;
}
*flag[pid]=2;
for (k=1; k<=n; k++)
if (k!=pid)
{
test=*flag[k];
if (test==2) goto L;
}
printf("\t\t\t\tP%d jest w sekcji krytycznej\n", pid);
sleep(random()%10);
*flag[pid]=0;
}
}
}
wait(NULL);
}

