|
|||||||
|
|
|
![]() |
|
|
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: 15:49.



















