Newsgroup: it.comp.os.linux.development
Titolo: semafori condivisi tra thread

Ho bisogno di usare dei semafori per regolare l'accesso ad un segmento di
memoria condivisa.
In un processo creo i semafori con:
semaforiVisione = semget (IPC_PRIVATE, 1, 0666 | IPC_CREAT);
poi in un altro programma che viene lanciato dal primo con una execlp ho:
struct sembuf sop[1];
 
void inline bloccaSemaforo (int sem) {
        printf ("blocco\n");
        sop[0].sem_op = 0;
        sop[0].sem_num = 0;
        semop(sem, sop, 1);
}
void inline sbloccaSemaforo (int sem) {
        printf ("sblocco\n");
        sop[0].sem_op = 1;
        sop[0].sem_num = 0;
        semop(sem, sop, 1);
}
e sem ha lo stesso valore di semaforiVisione, che viene passato dalla
execlp. Il problema è che queste due funzioni vengono chiamate dentro un
ciclo while dove aggiorno la struttura per evitare che il primo processo
vada a leggere dei dati incorretti e la prima prima volta che chiamo
blocca e sblocca funziona, la seconda volta che ciamo blocca si ferma
tutto.
Cosa cavolo può essere?

On Fri, 11 Apr 2003 08:53:57 +0200, Ottavio Campana wrote:
ecco, sono un po' scemo stamattina.
I semafori vanno condivisi tra task, non thread...
onde evitare confusione....

On Fri, 11 Apr 2003 09:02:31 +0200, Ottavio Campana 
was talkin'about:
#define IMHO

Non ho capito l'evoluzione del problema.
NP: Rainbow - Stargazer
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
  -<! Take It All, Our Gold, Our Homes, Our Life, But We Didn't Kill 
	    Your Christ! !>- Blind Guardian - The Script For My Requiem

> onde evitare confusione....
sei usi la libpthread hai i semafori di quella libreria e devi usare
sem_wait e sem_post e non ci sono problemi. Ma la libpthread di linux non
supporta i semafori condivisi tra task.
Allora penso di usare i semafori che mette a disposizione linux con le
ipc. Solo che non ho capito bene come si usino. Sono giuste le funzioni si
blocca e sblocca?

Allora sembra un bel deadlock o starvation.....
union semun {
        int val;                    /* value for SETVAL */
        struct semid_ds *buf;       /* Recer for IPC_STAT, IPC_SET */
        unsigned short int *array;  /* array for GETALL, SETALL */
        struct seminfo *__buf;      /* Recer for IPC_INFO */
        };
int		Semafori;		// ID set di semafori per scrivere
	union semun		sem_val;      // per settare il valore dei semafori
	struct sembuf	sem_op;     // struttura per operazioni sui semafori
// crea un set di semafori per il controllo dell'accesso al file id_sem=semget(chiave,NumeroSemafori,flag)
	Semafori = semget(IPC_PRIVATE, Nf, 0600);
        if (Semafori == -1) {
        	perror("main: semget");
      		exit(1);
	}
	sem_val.val = 1;                // inizializza sem a 1
	// rc=semctl(id_sem, posizione,comando,StrutturaSemaforo)
	for (i=0;i<Nf;i++) 
    		printf("Semaforo %d -> %d\n",i, semctl(Semafori, i, SETVAL, sem_val)); 'setto il tutto a 1
 
//funzione down	
void Down(int sem,int pos){
    struct sembuf sem_op;
	sem_op.sem_num = pos;
	sem_op.sem_op = -1;
	sem_op.sem_flg = 0;
	semop(sem, &sem_op, 1);
}
//funzione up	
void Up(int sem,int pos){
    struct sembuf sem_op;
    	sem_op.sem_num = pos;
	sem_op.sem_op = 1;
	sem_op.sem_flg = 0;
	semop(sem, &sem_op, 1);
}
 
Io implemento il tutto così, il valore dell'operazione è il numero che somma al valore attuale (se sommi 0 succede un casino)
Per lo meno da quel poco che ho capito dovrebbe funzionare così ^_^
P.S.
	tu hai informazioni su come è possibile condividere memoria tra THREADS e regolarne l'accesso?
-- 
Strhad
per stupire mezz'ora basta un libro di storia,
io cercai di imparare la Treccani a memoria... [F.d.A.]

 tra THREADS e regolarne l'accesso?
con libpthread nella libc se dichiari una variabile globale quella viene
condivisa da tutti i thread, quello che viene dichiarato nelle funzioni ha
lo scope limitato alla funzione stessa.
Non mi è mai capitato di aver bisogno di politiche più evolute di gestione
della memoria tra thread, però proverei a creare un segmento di memoria e
ad agganciarlo all'interno di ogni thread. Però non so se funzioni...

 ad agganciarlo all'interno di ogni thread. Perň non so se funzioni...
Non ha molto senso. La shared memory e' fatta per la condivisione fra
processi non fra thread.
Le primitive di sincronizzazione per i thread sono mutex
(pthread_mutex_init...), semafori (sem_init...) e condition variables
(pthread_cond_init...)
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
    -<! And the will shall return And again hearts shall burn
         All the horns now will sing Leading you back to the metal winds !>-
                  Lost Horizon - Sworn In The Metal Wind

 tutto.
Per un esempio prova a dare un'occhiata al cvs di mpg321, ci dovrebbe essere
un meccanismo produttore/consumatore con fifo condivisa e 2 semafori per la
gestione.


 gestione.
ok

 scegliere un file a caso o un file particolare?
La ftok serve per creare una chiave unica e comune a tutti i processi che
vogliono accedere ad una risorsa condivisa. Devi scegliere un file che non
sia "anonimo" (per esempio /tmp e` un cattivo esempio) ma piuttosto scegli
un file che sia specifico alla tua applicazione. Qualche suggerimento:
1) se usi una sola immagine, dai il path dell'immagine stessa (argv[0]):
questa e` la soluzione migliore
2) se usi una libreria comune e questa libreria e` specifica alla tua
applicazione (/usr/lib/libc.a e` da evitare ;-) ) usala (problema: se
la libreria viene usata anche da altre applicazioni e queste fanno un
ftok...)
3) un file di configurazione comune alle applicazioni (sempre che non sia
usato da altre applicazioni che fanno ftok...)
La chiave e`: il file deve essere specifico alla tua applicazione e devi
essere sicuro che altre applicazioni che girano sulla stessa macchina non
lo useranno per scopi simili.
Ciao,
-- 
       Roberto Divia`             Love at first sight is one of the greatest
       =============             labour-saving devices the world has ever seen.
Mailbox: C02110                 CERN-European Organization for Nuclear Research
E-mail: 
Robert...@cern.ch
           CH-1211 GENEVE 23, Switzerland

 scegliere un file a caso o un file particolare?
Per generare una chiave unica ti serve un nome di file "tuo". Per es il path
completo del prg.
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
	**ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail**
 -<! Woe to you, oh Earth and Sea, for the Devil sends the Beast with
      wrath, because He knows the time is short... !>- Revelations, XIII - 18