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;
}
}
}

