Witam, mam problem z implementacja algorytmu czytelników i pisarzy preferujących procesy piszące z zastosowaniem uogólnionych semaforów.

Pseudokody:
Operacja pn
PN(s,n)
zawieszenie procesu do czasu gdy s>=n
s:=s-n;

VN(s)
s:=s+n;

czytanie
begin
repeat
PN(r,M)
PN(w,1)
VN(r,M-1)
VN(r,1)
czytanie
VN(w,1)
end

pisanie
begin
repeat
PN(r,1)
PN(w,M)
pisanie
VN(w,M)
VN(r,1)
end

Oto mój kod:

///////////////////////// pis.c /////////////////////////
#include <stdio.h>
#include "operacje.h"
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <time.h>
#define MAX 10
#define MAX2 12
int main()
{
	key_t kluczs,kluczm;
	int semID;
	int shmID;
	int *bufor;
	int N=2;
	int i;
	#define odczyt bufor[MAX]
	#define zapis bufor[MAX+1]
	int M=100;
	printf("piszacy----------------\n");
	if((kluczs = ftok(".",'A')) == -1 ) { printf("Blad ftok (A) \n"); exit(2); }
	semID = alokujSem(kluczs, N, IPC_CREAT |0666);
	if(semID == -1){ printf("blad semafora - piszacy\n"); exit(1);}
	kluczm=ftok(".",'B');
	shmID=shmget(kluczm,MAX2*sizeof(int), IPC_CREAT | 0666 );
	if(shmID == -1) {printf("blad pamieci dzielonej\n"); exit(1);}
	bufor=(int*)shmat(shmID,NULL, 0);	
	PN(semID,0, 1);
	PN(semID,1, M);
	for(i=0;i<MAX;i++)
	{
		bufor[zapis]=i;
		zapis=(zapis+1) % MAX;
		fprintf(stderr,"zapisalem %d\n",bufor[i]);
	}
	VN(semID,1,M);
	VN(semID,0,1);
	printf("piszacy skonczyl\n");
}


/////////////////////// czyt.c //////////////////////////
#include <stdio.h>
#include "operacje.h"
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <time.h>
#define MAX 10
#define MAX2 12
int main()
{
	key_t kluczs,kluczm;
	int semID;
	int shmID;
	int *bufor;
	int N=2;
	int i;
	#define odczyt bufor[MAX]
	#define zapis bufor[MAX+1]
	int M=10;
	printf("czytajacy----------------\n");
	if((kluczs = ftok(".",'A')) == -1 ) { printf("Blad ftok (A) \n"); exit(2); }
	semID = alokujSem(kluczs, N, IPC_CREAT |0666);
	if(semID == -1){ printf("blad semafora - producent\n"); exit(1);}
	kluczm=ftok(".",'B');
	shmID=shmget(kluczm,MAX2*sizeof(int), IPC_CREAT | 0666 );
	if(shmID == -1) {printf("blad pamieci dzielonej\n"); exit(1);}
	bufor=(int*)shmat(shmID,NULL, 0);
	PN(semID,0, M);
	PN(semID,1, 1);
	VN(semID,0,M-1); 
	VN(semID,0,1); 
	for(i-0;i<MAX;i++)
	fprintf(stderr,"czytam %d \n",bufor[i]);	
	VN(semID,1, 1);
	printf("czytajacy skonczyl\n");
}
///////////////////////////////// mainprog.c ///////////////////////////////////////////
#include <stdio.h>
#include <string.h>
#include "operacje.h"
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#define P 10
#define MAX 10
#define MAX2 12
#define PUSTY 1
#define PELNY 2
struct bufor{
long mtype;
int mvalue;
};
int main()
{
key_t kls,klm;
int semID;
int N = 2;
int i;
int shmID;
if( (kls = ftok(".",'A')) == -1 ) { printf("Blad ftok (main)\n"); exit(1) ; }
semID = alokujSem(kls, N, IPC_CREAT | IPC_EXCL | 0666);
inicjalizujSem(semID, 0, 0);//r
inicjalizujSem(semID, 1, 0);//w
printf("Semafor gotowy!\n");
klm=ftok(".",'B');
shmID=shmget(klm,MAX2*sizeof(int), IPC_CREAT|IPC_EXCL|0666);
if(shmID==-1) {printf("Blad shm\n"); exit(1);}
fflush(stdout);
for(i = 0; i < P; i++)
switch (fork())
{
case -1:
	perror("Blad fork (mainprog)");
	exit(2);
case 0:
	execl("./pisz","pisz", NULL );
}
for(i=0;i<P;i++)
switch(fork())
{
case -1:
	printf("Blad fork (mainprog)");
	exit(2);
case 0:
	execl("./czyt","czyt",NULL);
}
for(i=0;i<2*P;i++) wait(NULL);
zwolnijSem(semID,N);
shmctl(shmID,IPC_RMID,NULL);
printf("MAIN: KONIEC.\n");

}


//////////////////////////////////////////// operacje.c /////////////////////////////////////////
#include "operacje.h"
int alokujSem(key_t klucz, int number, int flagi)
{
	int semID;
	if( (semID = semget(klucz,number,flagi)) == -1) { perror("Blad semget (alokujSemafor): "); exit(1); }
	return semID;
}
int zwolnijSem(int semID, int number)
{
	return semctl(semID, number, IPC_RMID , NULL);

}
void inicjalizujSem(int semID, int number,int val)
{
	if (semctl(semID,number,SETVAL,val) == -1 ) { perror("Blad semctl (inicjalizujSemafor): "); exit(1); }

}

int PN(int semID,int number, int n)
{
	struct sembuf operacje;
	operacje.sem_num = number;
	operacje.sem_op = -n;
	operacje.sem_flg = 0;
	if(semop(semID, &operacje , 1) == -1) { perror("Blad semop(PN)"); return -1;}
	return 1;
}
int VN(int semID,int number,int n)
{
	struct sembuf operacje;
	operacje.sem_num = number;
	operacje.sem_op = n;
	operacje.sem_flg = 0;
	if(semop(semID, &operacje , 1) == -1) { perror("Blad semop(VN)"); return -1;}
	return 1;
}


//////////////////////////////// operacje.h ///////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/errno.h>
int alokujSem(key_t klucz, int number, int flagi);
void inicjalizujSem(int semID,int number,int val);
int zwolnijSem(int semID,int number);
int PN(int semID,int number, int n);
int VN(int semID,int number,int flags);

Po odpaleniu wyniki są takie ( program się zawiesza)

Semafor gotowy!
piszacy----------------
piszacy----------------
piszacy----------------
piszacy----------------
piszacy----------------
piszacy----------------
piszacy----------------
piszacy----------------
piszacy----------------
czytajacy----------------
czytajacy----------------
czytajacy----------------
czytajacy----------------
czytajacy----------------
czytajacy----------------
czytajacy----------------
czytajacy----------------
czytajacy----------------
czytajacy----------------
piszacy----------------

Proszę o pomoc w znalezieniu i rozwiązaniu problemu ...