PDA

Visualizza la versione completa : [C]semafori in windows


Gil Mour
19-11-2003, 01:26
ho un problema con la gestione dei semafori, il codice e' questo postato sotto, e il problema e' semplice: il semaforo viene semplicemente ignorato...ovvero il processo 1 manda la wait al semaforo ed entra nella sua sezione critica...e il processo 2 riesce a entrare nella sua sezione critica prima che il processo 1 abbia rilasciato il semaforo stesso

se compilate ed eseguite il risultato finale e'
Processo1 in sezione critica
Processo2 in sezione critica
Processo1 uscito dalla sez.
Processo2 uscito dalla sez.

e poi infine mi manda il msg "errore rilascio semaforo nel processo2"...

qualcuno puo aiutarmi?

//main
if (argc==1) {
//processo1
sem = CreateSemaphore(NULL,1,1,"mio_semaforo");
if (sem==NULL) puts("Errore nella creazione del semaforo (processo padre)");
proc = CreateProcess("prova_semafori.exe","prova_semafori.exe figlio",
NULL,
NULL,
TRUE,
NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&s,
&p);


if (proc==0) printf("Chiamata fallita\n");
WaitForSingleObject(sem,INFINITE);
puts("Processo 1 in sezione critica");
system("PAUSE");
if(!ReleaseSemaphore(sem,1,NULL))puts("errore rilascio semaforo processo 1");
puts("Processo 1 Uscito dalla sezione critica");
system("PAUSE");
}
else {
//processo2
sem = OpenSemaphore(MUTEX_ALL_ACCESS,FALSE,"mio_semaforo");
if (sem==NULL) puts("Errore nell'apertura del semaforo (processo figlio)");
WaitForSingleObject(sem,INFINITE);
puts("Processo 2 in sezione critica");
system("PAUSE");
if(!ReleaseSemaphore(sem,1,NULL)) puts("errore rilascio semaforo processo 2");
puts("Processo 2 Uscito dalla sezione critica");
system("PAUSE");
}
return 0;

Gil Mour
20-11-2003, 17:31
visto il successo riscosso dal mio post provo a porre la questione in un altro modo: qualcuno mi spiega se questo modo di gestire i semafori e' corretto?

/*creo cosi il semaforo nel processo padre*/
sem = CreateSemaphore(NULL,1,1,"mio_semaforo");

WaitForSingleObject(sem,INFINITE);
//faccio quello che devo fare
ReleaseSemaphore(sem,1,NULL);

/*apro il semaforo nel processo figlio*/
sem = OpenSemaphore(MUTEX_ALL_ACCESS,FALSE,"mio_semaforo");

WaitForSingleObject(sem,INFINITE);
//fa quel che deve fare
ReleaseSemaphore(sem,1,NULL);

1.intanto vorrei sapere se un procedimento cosi e' corretto.

2.aggiungo che in esecuzione viene fuori un errore runtime dalla funzione release semaphore del processo figlio.

3.Quali sono (e cosa signifcano) le altre costanti letterali possibili per il primo argomento di OpenSemaphore ?

grazie!

$$$
20-11-2003, 17:47
dovresti usare SEMAPHORE_ALL_ACCESS
invece che MUTEX_ALL_ACCESS per correttezza-

gli altri flag sono SEMAPHORE_MODIFY_STATE
solo x il release del semaforo e SYNCHRONIZE
per win2k/nt/xp/2k3 per abilitare il semaforo
ad essere usato nelle funzioni di attesa/sincronizzazione-

Gil Mour
20-11-2003, 17:54
questa cosa di semaphore_modify_state l'ho letta pure su msdn, ma non l'ho capita

cioe', quello non dovrebbe essere un parametro per i permessi di accesso? che c'entra la release ? non e' ovvio che se uso un semaforo lo dovro rilasciare prima o poi?

:dottò:

quindi l'esempio che ho postato non dovrebbe funzionare?

ps.:sono sotto win 2k

$$$
20-11-2003, 20:07
Originariamente inviato da Gil Mour
questa cosa di semaphore_modify_state l'ho letta pure su msdn, ma non l'ho capita

cioe', quello non dovrebbe essere un parametro per i permessi di accesso? che c'entra la release ? non e' ovvio che se uso un semaforo lo dovro rilasciare prima o poi?

:dottò:

quindi l'esempio che ho postato non dovrebbe funzionare?

ps.:sono sotto win 2k


non so se funziona o no :)
devi vedere se MUTEX_ALL_ACCESS e SEMAPHORE_ALL_ACCESS
coincidono (in valore)

cmq a te basta solo decrementare il semaforo quindi ti serve
solo utilizzare la release, per cui x evitare problemi
non chiedere privilegi che nn ti servono :)

ps= hai provato ad usare gli EVENTS al posto dei semafori?
credo faccia a caso tuo....

Loading