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.
peterson2.c:
//(c)2002 Tomasz Lubinski
//www.algorytm.org
//algorytm Peterson'a dla 2 procesow - 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* flag[2];
int* turn;
int other, whose;
//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);
flag[0]=shmat(shmid, NULL, SHM_RND);
*flag[0]=0;
shmid=shmget(102, 4, IPC_CREAT);
shmctl(shmid, IPC_STAT, &buf);
buf.shm_perm.mode=0666;
shmctl(shmid, IPC_SET, &buf);
flag[1]=shmat(shmid, NULL, SHM_RND);
*flag[1]=0;
shmid=shmget(103, 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=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 Peterson'a dla 2 procesow
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");
*flag[0]=1;
*turn=1;
do
{
whose=*turn;
other=*flag[1];
} while(whose==1&&other==1);
printf("\t\t\tP1 jest w sekcji krytycznej\n");
sleep(random()%10);
*flag[0]=0;
}
}
else
{
//proces 2
while(1)
{
printf("P2 jest poza sekcja krytyczna\n");
sleep(random()%10);
printf("P2 chce wejsc do sekcji krytycznej\n");
*flag[1]=1;
*turn=0;
do
{
whose=*turn;
other=*flag[0];
} while(whose==0&&other==1);
printf("\t\t\tP2 jest w sekcji krytycznej\n");
sleep(random()%10);
*flag[1]=0;
}
}
}

