Witam,
Mam na zadanie Problem 5 filozofów na kolejkach komunikatów rozwiązanie na stanach w języku C. Napisałem program dla filozofa oraz main na podstawie pseudo kodu, który mieliśmy w skrypcie i który załączam na dole. Problem jest w tym, że program działa do pewnego momentu, i po jakimś czasie już nic się nie dzieje. Tak jakby cała kolejka się zwolniła, nie wiem w czym jest problem gdyż kod pisałem w oparciu o pseudokod ze skryptu. Proszę o jakieś wskazówki co mogę robić źle i czemu tak się dzieje.
Pseudo kod wygląda następująco:
stan[i]=0 – myślenie
stan[i]=1 – chęć jedzenia
stan[i]=2 – jedzenie
var widelec: array[0..4] of recource;
sem: array[0..4] of Boolean semaphore:=false;
stan: array[0..4] of integer:=0; /myślenie
w: Boolean semaphore:=true;
procedure test(k:integer);
begin
if stan[(k-1) mod 5]<>2 and stan[k]=1 and stan[(k+1) mod 5]<>2
then
stan[k]:=2;
signal(sem[k]);
end
end
Kod filozofa:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#define PHIL_COUNT 5
#define fil 5
#define W 15
void thinking();
void eating();
void showForks();
struct msgStructure
{
long msgType;
int mVal;
};
key_t widelceKolejkaKlucz;
key_t filozofKolejkaKlucz;
key_t memKey;
int widelceID;
int filozofyID;
int philID;
int memID;
int *stan; //tablica widelcow
int i;
int loops;
struct msgStructure message;
void test(int nr_filozofa) {
if(stan[(nr_filozofa-1)%5] != 2 && stan[nr_filozofa] == 1 && stan[(nr_filozofa+1)%5] !=2)
{
stan[nr_filozofa - 1] =2;
message.msgType = nr_filozofa;
msgsnd(filozofyID, &message, sizeof(message.mVal), 0);
}
}
int main(int argc, char *argv[])
{
philID = atoi(argv[2]);
loops = atoi(argv[1]);
srand(time(NULL));
if ((widelceKolejkaKlucz = ftok(".", 'A')) == -1) {
fprintf(stderr, "Linia %d: ftok(queueKey) zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
if ((filozofKolejkaKlucz = ftok(".", 'C')) == -1) {
fprintf(stderr, "Linia %d: ftok(queueKey) zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
if ((widelceID=msgget(widelceKolejkaKlucz,0666)) == -1) {
fprintf(stderr, "Linia %d: msgget zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
if ((filozofyID=msgget(filozofKolejkaKlucz, 0666)) == -1) {
fprintf(stderr, "Linia %d: msgget zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
if ((memKey = ftok(".", 'B')) == -1)
{
fprintf(stderr, "Linia %d: ftok(memKey) zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
if ((memID = shmget(memKey, PHIL_COUNT*sizeof(int), 0666))==-1)
{
fprintf(stderr, "Linia %d: shmget zakonczony bledem: %d\n",__LINE__, errno);
exit(EXIT_FAILURE);
}
fflush(stdout);
if ((stan = (int*)shmat(memID, NULL, 0)) == (int*) - 1)
{
fprintf(stderr, "Linia %d: shmat zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
for (i = 0; i < loops; i++)
{
thinking(); //myslenie
msgrcv(filozofyID, &message, sizeof(message.mVal), W, 0); //wait(w)
// stan[philID-1] = 1; // stan[name]:=1
stan[philID] = 1;
// test(philID-1); // test(name)
test(philID);
message.msgType = W;
msgsnd(filozofyID, &message, sizeof(message.mVal), 0); //signal(w)
showForks();
msgrcv(filozofyID, &message, sizeof(message.mVal), philID, 0); // wait(sem[name])
// request (widelec[name],widelec[(name+1)mod5]);
msgrcv(widelceID, &message, sizeof(message.mVal), philID, 0);
msgrcv(widelceID, &message, sizeof(message.mVal), (philID+1)%6, 0);
//=================================================
//jedzenie;
eating();
//release(widelec[name],widelec[(name+1)mod5]);
message.msgType = philID;
msgsnd(widelceID, &message, sizeof(message.mVal), 0);
message.msgType = (philID+1) % 6;
msgsnd(widelceID, &message, sizeof(message.mVal), 0);
//=========================================
msgrcv(filozofyID, &message, sizeof(message.mVal), W, 0); //wait(w)
stan[philID-1] = 0; //stan[name]:=0;
test((philID+1)%6);//test((name+1)mod 5);
// test(philID==1 ? 4 : philID-2);//test((name-1)mod 5);
test((philID-1)%6);
showForks();
message.msgType = W;
msgsnd(filozofyID, &message, sizeof(message.mVal), 0); //signal(w)
/* int leftFork, rightFork;
if (philID==1)
{
msgrcv(queueID, &message, sizeof(message.mVal), 1, 0); //lewy
leftFork=1;
rightFork=5;
msgrcv(queueID, &message, sizeof(message.mVal), 5, 0); //prawy
}
else
{
msgrcv(queueID, &message, sizeof(message.mVal), philID-1, 0); //prawy
msgrcv(queueID, &message, sizeof(message.mVal), philID, 0); //lewy
leftFork=philID;
rightFork=philID-1;
}
pForksTab[leftFork-1] = philID;
pForksTab[rightFork-1] = philID;
eating();
message.msgType = leftFork;
msgsnd(queueID, &message, sizeof(message.mVal), 0);
message.msgType = rightFork;
msgsnd(queueID, &message, sizeof(message.mVal), 0);
pForksTab[leftFork-1] = 0;
pForksTab[rightFork-1] = 0;
*/
}
}
void thinking()
{
printf("Filozof %d mysli\n", philID);
sleep(rand()%4);
}
void eating()
{
printf("___________________\nFilozof %d je... \n", philID);
sleep(1);
showForks();
printf("Filozof %d skonczyl jesc.\n", philID);
}
void showForks()
{
int i;
printf("\nTablica stanow: ");
for (i = 0; i < PHIL_COUNT; i++)
printf(" %d ", stan[i]);
printf("\n");
}
A kod pliku main tak:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <signal.h>
#define PHIL_COUNT 5
#define W 15
struct msgStructure
{
long msgType;
int mVal;
};
key_t widelceKolejkaKlucz;
key_t filozofKolejkaKlucz;
key_t memKey;
int widelceID;
int filozofyID;
int philID;
int memID;
int *pForksTab; //tablica widelcow
void sig_handler(int signo)
{
if (signo != SIGINT)
return;
msgctl(widelceID, IPC_RMID, NULL);
msgctl(filozofyID, IPC_RMID, NULL);
exit(EXIT_SUCCESS);
}
int main(int argc, char *argv[])
{
int i;
int philID = 1;
struct msgStructure message;
char argument[2];
signal(SIGINT, sig_handler);
printf("Ustawianie...\n");
if ((widelceKolejkaKlucz = ftok(".", 'A')) == -1) {
fprintf(stderr, "Linia %d: ftok(queueKey) zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
if ((filozofKolejkaKlucz = ftok(".", 'C')) == -1) {
fprintf(stderr, "Linia %d: ftok(queueKey) zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
if ((widelceID=msgget(widelceKolejkaKlucz, IPC_CREAT|0666)) == -1) {
fprintf(stderr, "Linia %d: msgget zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
if ((filozofyID=msgget(filozofKolejkaKlucz, IPC_CREAT|0666)) == -1) {
fprintf(stderr, "Linia %d: msgget zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
for (i = 1; i <= PHIL_COUNT; i++) {
message.msgType=i;
msgsnd(widelceID, &message, sizeof(message.mVal), 0);
}
message.msgType=W; //ustawianie pseudo-semafora na 1
msgsnd(filozofyID, &message, sizeof(message.mVal), 0);
if ((memKey=ftok(".", 'B')) == -1) {
fprintf(stderr, "Linia %d: Liftok(memKey) zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
if ((memID=shmget(memKey, PHIL_COUNT*sizeof(int), IPC_CREAT|0666)) == -1) {
fprintf(stderr, "Linia %d: shmget zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
if ((pForksTab = (int*)shmat(memID, NULL, 0)) == (int*) - 1) {
fprintf(stderr, "Linia %d: shmat zakonczony bledem: %d\n", __LINE__, errno);
exit(EXIT_FAILURE);
}
for (i=0; i<PHIL_COUNT; i++)
pForksTab[i]=0;
printf("Tworzenie procesow filozofow.\n");
for (i=1; i<=PHIL_COUNT; i++)
switch (fork()) {
case -1:
fprintf(stderr, "Linia %d: Fork zakonczony bledem", __LINE__);
exit(EXIT_FAILURE);
case 0:
sprintf(argument, "%d", i);
execl("./filozof", "filozof", "10", argument, NULL);
}
for (i=1; i<=PHIL_COUNT; i++)
wait(NULL);
sig_handler(SIGINT);
printf("MAIN: Koniec.\n");
}