|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Linux, C e semafori: dove sbaglio??
Olevo provare a risolvere il calssico problema di IPC del Produttore e Consumatore con buffer limitato (nel mio caso 4 elementi)...
Ho scritto questo codice, ma non funziona ![]() Codice:
#include<stdio.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/shm.h> #include<sys/sem.h> #define ARRAY_LENGTH 2 #define BUF_DIM 4 main() { int f; int in=0,out=0; int empty,full; char nextp,nextc; struct sembuf sops[ARRAY_LENGTH]; int semid; //char buffer[10]; //char *pun; semid = semget(IPC_PRIVATE,ARRAY_LENGTH,0666); //4 semafori nel set, r/w x tutti! printf("prelevato set di semafori id = %d\n",semid); empty = semctl(semid,0,SETVAL,BUF_DIM); full = semctl(semid,1,SETVAL,0); printf("Valore iniziale dei semafori:\n"); printf("EMPTY: %d\n",semctl(semid,0,GETVAL,0)); printf("FULL: %d\n",semctl(semid,1,GETVAL,0)); f = fork(); if (f == -1) { fprintf(stderr,"fork fallita\n"); exit(1); } else if (f !=0) { //P while (1){ //nextp = 'x'; printf("\n(P) -- wait(empty) -- tento di decrementare il semaforo EMPTY %d\n",semctl(semid,0,GETVAL,0)); //wait(empty) se il valore del sem EMPTY è 0 nn mi fa andare avanti!! sops[0].sem_num = 0; /* operazione sul semaforo 1 */ sops[0].sem_op = -1; /* decrementa il semaforo di 1 */ sops[0].sem_flg = 0; /* che fare: wait se == 0 */ empty = semop(semid,sops,1); //1: lunghezza dell'array sops printf("\n(P) ho decrementato il semaforo EMPTY: %d\n", semctl(semid,0,GETVAL,0)); //buffer[in]= nextp; system("sleep 10"); //P + lento di C printf("\n(P) ho prodotto l'elemento %d\n", in); in = (in +1) % BUF_DIM; printf("\n(P) -- signal(empty) -- tento di incrementare il semaforo FULL %d\n",semctl(semid,1,GETVAL,0)); //signal(full) incremento FULL sops[1].sem_num = 1; /* operazione sul semaforo 2 */ sops[1].sem_op = 1; /* incrementa semaforo 2*/ sops[1].sem_flg = 0; /* che fare: ??*/ full = semop(semid,sops,1); printf("\n(P) - ho incrementato il semaforo FULL: %d\n" , semctl(semid,1,GETVAL,0)); } exit(0); //semctl(semid,IPC_RMID,0); //printf("(P) Rilasciato i sem, ora muoio... \n"); } else { //C while (1){ printf("\n(C) -- wait(full) -- tento di decrementare il semaforo FULL: %d\n",semctl(semid,1,GETVAL,0)); //wait(full) sops[1].sem_num = 1; /* operazione sul semaforo 0 */ sops[1].sem_op =-1; /* decrementa il semaforo di 1 */ sops[1].sem_flg = 0; /* che fare: wait se semaforo = 0 */ full = semop(semid,sops,1); //1: lunghezza dell'array sops printf("\n(C) ho decrementato il semaforo FULL: %d\n" , semctl(semid,1,GETVAL,0)); //nextc=buffer[out]; system("sleep 1"); printf("\n(C) ho consumato l'elemento %d\n", out); out = (out +1) % BUF_DIM; printf("\n(C) -- signal(empty) -- tento di incrementare il semaforo EMPTY - signal(EMPTY) %d\n" , semctl(semid,0,GETVAL,0)); //signal(empty) sops[0].sem_num = 0; /* operazione sul semaforo 0 */ sops[0].sem_op = 1; /* incrementa il semaforo di 1 */ sops[0].sem_flg = 0; /* che fare: ?? */ empty = semop(semid,sops,1); printf("\n(C) -ho incrementato il semaforo EMPTY - signal(EMPTY) %d\n" , semctl(semid,0,GETVAL,0)); } } } |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Codice:
--- sem.c.org 2004-04-02 09:03:57.000000000 +0200 +++ sem.c 2004-04-02 09:03:31.000000000 +0200 @@ -62,7 +62,7 @@ sops[1].sem_num = 1; /* operazione sul semaforo 2 */ sops[1].sem_op = 1; /* incrementa semaforo 2*/ sops[1].sem_flg = 0; /* che fare: ??*/ - full = semop(semid,sops,1); + full = semop(semid,sops+1,1); printf("\n(P) - ho incrementato il semaforo FULL: %d\n" , semctl(semid,1,GETVAL,0)); @@ -84,7 +84,7 @@ sops[1].sem_op =-1; /* decrementa il semaforo di 1 */ sops[1].sem_flg = 0; /* che fare: wait se semaforo = 0 */ - full = semop(semid,sops,1); //1: lunghezza dell'array sops + full = semop(semid,sops+1,1); //1: lunghezza dell'array sops printf("\n(C) ho decrementato il semaforo FULL: %d\n" , semctl(semid,1,GETVAL,0)); //nextc=buffer[out]; system("sleep 1");
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Per cortesia fammi capire...
intendi togliere per il semaforo FULL - full = semop(semid,sops,1); e sostituirlo con + full = semop(semid,sops+1,1); ?? Io avevo capito questo: Quote:
|
|
![]() |
![]() |
![]() |
#4 | ||
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
man diff ![]() Quote:
Nel tuo caso compi una unica operazione su un unico semaforo alla volta, quindi potevi anche non usare un array.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
||
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
full = semop(semid,sops+1,1);
sops +1 è l'indirizzo dell'elemento dell'array che contiene il semaforo sul quale voglio aplllicare l'operazione? il terzo parametro (nops =1) che cavolo indica? ![]() |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Per non riscrivere sempre il codice dei semafori è corretto implementare due funzioni P e V in questo modo?
Codice:
P(struct sembuf sems[ARRAY_LENGTH], int index, int semid){ sems[index].sem_num = index; /* operazione sul semaforo 0 */ sems[index].sem_op = -1; /* incrementa il semaforo di 1 */ sems[index].sem_flg = 0; /* che fare: ?? */ return semop(semid,sems + index,1); } V(struct sembuf sems[ARRAY_LENGTH], int index, int semid){ sems[index].sem_num = index; /* operazione sul semaforo 0 */ sems[index].sem_op = +1; /* incrementa il semaforo di 1 */ sems[index].sem_flg = 0; /* che fare: ?? */ return semop(semid,sems + index,1); } |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Ti stai solo complicando la vita...
struct sembuf s; s.sem_flg = 0; s.sem_op = -1; s.sem_num = 0; semop(semid, &s, 1); s.sem_op = 1; s.sem_num = 1; semop(semid, &s, 1);
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Allora diciamo che un array di semafori è utile quando si devono eseguire operazioni unuitarie contemporaneamente su + semafori.Se devo eseguire una sola operazion alla volta su n semafori conviene definire 2 diversi semafori:
struct sembuf s1; struct sembuf s2; E' corretto? |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Se le operazioni non vengono effettuate in contemporanea (ad es. da due thread) puoi anche usare una unica struct sembuf
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Ho capito!
struct sembuf sops; ... prelevo n semafori semid = semget(IPC_PRIVATE,n,0666); e poi uso P(i) e V(i) dove Codice:
P(int sem ){ sops.sem_num = sem; /* operazione sul semaforo 0 */ sops.sem_op = -1; /* incrementa il semaforo di 1 */ sops.sem_flg = 0; /* che fare: ?? */ return semop(semid,sops,1); } V(int sem){ sops.sem_num = sem; /* operazione sul semaforo 0 */ sops.sem_op = +1; /* incrementa il semaforo di 1 */ sops.sem_flg = 0; /* che fare: ?? */ return semop(semid,sops ,1); } |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 03:55.