c - Why does my producer-consumer blocks? -
that's simple (almost)solution producer-consumer problem. uses wait , signal functions, blocks on 1 of waits.
here files: prod.c
int *pam; #define max 10 #define max2 12 #define pusty 2 //empty #define s1 0 #define pelny 1 //full #define zapis pam[max+1] //write #define odczyt pam[max] //read int main() { int i; time_t czas; key_t klucz, kluczm; int semid; int shmid; int n=3; printf("producer--------------------------------\n"); if((klucz=ftok(".", 'a')) == -1) {printf("blad ftok (a)\n"); exit(2);}; semid=alokujsem(klucz, 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 - producent\n");exit(1);} pam=(int*)shmat(shmid, null, 0); time(&czas); i=((int)czas)%100; waitsemafor(semid, pusty, 0); waitsemafor(semid, s1, 0); pam[zapis]=i; zapis=(zapis+1)%max; printf("wyprodukowano: %d\n", pam[zapis]); signalsemafor(semid, s1); signalsemafor(semid, pelny); printf("po signal - producent\n"); }
kons.c
int *pam; #define max 10 #define max2 12 #define pusty 2 //empty #define s1 0 #define pelny 1 //full #define zapis pam[max+1] //write #define odczyt pam[max] //read int main() { key_t klucz, kluczm; int semid, shmid; int i; int n =3; printf("consumer------------------------------------\n"); if( (klucz=ftok(".", 'a')) == -1) { printf("blad frok(a)\n"); exit(2); } semid=alokujsem(klucz, n, ipc_creat | 0666);//allocate semaphores if(semid==-1) {printf("blad semafora-konsument\n"); exit(1);}; klucz = ftok(".", 'b'); shmid = shmget(kluczm, max2*sizeof(int), ipc_creat|0666);//adding shared memory if(shmid==-1) {printf("blad pamieci dzielonej-konsument\n");exit(1);}; pam=(int*)shmat(shmid, null, 0); waitsemafor(semid, pelny, 0); waitsemafor(semid, s1, 0); printf("konsumuje %d \n",pam[odczyt]); odczyt=(odczyt+1)%max; signalsemafor(semid, s1); signalsemafor(semid, pusty); printf("konsument skonczyl\n"); }
operacje.c
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 waitsemafor(int semid, int number, int flags) { printf("wszedłem wait z numerem %d", number); struct sembuf operacje[1]; operacje[0].sem_num = number; operacje[0].sem_op = -1; operacje[0].sem_flg = sem_undo; if ( semop(semid, operacje, 1) == -1 ) { printf("semop error: %s\n", strerror(errno)); perror("blad semop (waitsemafor)"); return -1; } return 1; } void signalsemafor(int semid, int number) { struct sembuf operacje[1]; operacje[0].sem_num = number; operacje[0].sem_op = 1; operacje[0].sem_flg = sem_undo; if (semop(semid, operacje, 1) == -1 ) perror("blad semop (postsemafor): "); }
i don't know why, doesn't print printf("...") waitsemafor().
and mainp.c
#define p 2 // processes amount #define max 10 #define max2 12 #define pusty 2 //empty #define s1 0 #define pelny 1 //full int main() { key_t klucz, kluczm; int semid; int shmid; int i; int n=3; if ( (klucz = ftok(".", 'a')) == -1 ) { printf("blad ftok (main)\n"); exit(1); } semid=alokujsem(klucz, n, ipc_creat | ipc_excl | 0666); inicjalizujsem(semid, s1, 1); inicjalizujsem(semid, pelny, 0); inicjalizujsem(semid, pusty, max); printf("semaphore ready!\n"); kluczm=ftok(".",'b'); shmid=shmget(kluczm, max2*sizeof(int), ipc_creat|ipc_excl|0666); for(i=0; i< p; i++) switch(fork()) { case -1: perror("blad fork(mainprog)"); exit(2); case 0: execl("./prod", "prod", null); } for(i=0; i<p; i++) switch(fork()) { case -1: printf("blad fork (mainprog)\n"); exit(2); case 0: execl("./kons", "kons", null); } for(i=0; i<2*p;i++) { wait(null); } zwolnijsem(semid,n); //release semaphore shmctl(shmid,ipc_rmid, null); printf("main: koniec.\n"); }
the thins printed console are:
semaphore ready! consumer------------------------------------ consumer------------------------------------ producer-------------------------------- producer--------------------------------
and hangs right there. order strange, producer should first.
i use gcc compile it, , looks this:
- gcc -c -o operacje operacje.c
- gcc -o kons kons.c operacje
- gcc -o prod prod.c operacje
- gcc -o mainp mainp.c operacje
- and run "./mainp"
i grateful ideas or solutions.
Comments
Post a Comment