Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Mutex
Forum - C/C++ - Mutex

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
robrock80 (Normal User)
Pro


Messaggi: 143
Iscritto: 11/12/2006

Segnala al moderatore
Postato alle 15:42
Giovedì, 25/03/2010
Salve a tutti. Ho scritto 2 funzioncine per inviare MessageBox, ma non funzionano, probabilmente uso male i mutex, ecco il codice

Codice sorgente - presumibilmente C#

  1. typedef struct _Params {
  2.                 void *param[11];
  3.                 void *returned[11];
  4.                 void (*function[11])(struct _Params *);
  5.         } Params;
  6.  
  7. HANDLE sendAsynchronousMessage(TCHAR title[], TCHAR text[], int type) {
  8.         DWORD dwThreadId;
  9.         HANDLE mutex = CreateMutex(NULL,FALSE,NULL);
  10.         Params params = {{(TCHAR*)title,(TCHAR*)text, &type, &mutex}};
  11.         HANDLE hThread = CreateThread(
  12.                                         NULL,   //Choose default security
  13.                                         0,              //Default stack size
  14.                                         (LPTHREAD_START_ROUTINE)&sendMessage,
  15.                                         &params,
  16.                                         0,              //Lancia il Thread immediatamente
  17.                                         &dwThreadId);
  18.         WaitForSingleObject(mutex, INFINITE);
  19.         printf("mutex rilasciato\n");
  20.         return hThread;
  21. }
  22.  
  23.  
  24. DWORD sendMessage(LPVOID param) {
  25.         Params* params = (Params*)param;
  26.         HANDLE mutex = (HANDLE*)params->param[3];
  27.         TCHAR* title = (TCHAR*)malloc(sizeof(TCHAR) * _tcslen((TCHAR*)params->param[0]));
  28.         _tcscpy(title,(TCHAR*)params->param[0]);
  29.         TCHAR* message = (TCHAR*)malloc(sizeof(TCHAR) * _tcslen((TCHAR*)params->param[1]));
  30.         _tcscpy(message,(TCHAR*)params->param[1]);
  31.         if (mutex != 0) {
  32. printf("entrato\n");
  33.                 ReleaseMutex(mutex);
  34.         }
  35.         MessageBox( NULL, message, title, *(int*)params->param[2]);
  36.         free(title);
  37.         free(message);
  38.         return 0;
  39. }



Praticamente mi salta il wait del mutex, dove sbaglio?

Ultima modifica effettuata da robrock80 il 25/03/2010 alle 16:02
PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 15:56
Giovedì, 25/03/2010
il mutex lo devi rilasciare DOPO che l'utente ha chiuso la MessageBox, altrimenti lo rilascia così rapidamente che la wait dura pochi nanosecondi...

PM Quote
Avatar
robrock80 (Normal User)
Pro


Messaggi: 143
Iscritto: 11/12/2006

Segnala al moderatore
Postato alle 16:01
Giovedì, 25/03/2010
Aspetta... vedi i 2 printf?
Mi stampa praticamente prima "rilasciato" e poi "entrato", mentre io mi aspetto che quando arriva alla wait il programma si ferma in attesa della release, invece non aspetta la release e va avanti

Ultima modifica effettuata da robrock80 il 25/03/2010 alle 16:03
PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 16:21
Giovedì, 25/03/2010
l'ordine dei printf non è affidabile. Vengono bufferizzati dalla console in modo del tutto asincrono. Puoi forzare la scrittura mettendo un fflush() dopo ogni printf(), ma questo interviene solo sul secondo livello di bufferizzazione (quello del VFS del kernel, che tratta lo standard output come un vero e proprio file), quindi non è garantito nemmeno in questo caso l'ordinamento corretto delle stringhe...

PM Quote
Avatar
robrock80 (Normal User)
Pro


Messaggi: 143
Iscritto: 11/12/2006

Segnala al moderatore
Postato alle 16:27
Giovedì, 25/03/2010
Ma c'è un modo sicuro per stampare in maniera sincronizzata?

Ultima modifica effettuata da robrock80 il 25/03/2010 alle 16:27
PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 16:33
Giovedì, 25/03/2010
quando si entra nel campo del multithreading, la sincronizzazione diventa un argomento difficile da trattare.
Se usi una console normale (con il normale printf) devi accollarti l'incertezza dell'ordine di arrivo. L'ordine è garantito solo all'interno dello stesso thread.
Questo è un limite intrinseco.

Probabilmente esistono versioni "sicure" e sincronizzate di printf, ma devi consultare approfonditamente le API di windows per fare questo, perchè il C standard non contempla nemmeno l'esistenza dei thread e delle primitive di sincronizzazione...

Non conosco approfonditamente windows, quindi lascio ad altri la palla :P

PM Quote
Avatar
robrock80 (Normal User)
Pro


Messaggi: 143
Iscritto: 11/12/2006

Segnala al moderatore
Postato alle 16:37
Giovedì, 25/03/2010
Comunque, qui non è un problema di printf, perchè ho provato a sostituire la wait con lo Sleep(1000) e il programma funziona. Tra l'altro non posso mettere la Release dopo MessageBox altrimenti perdo il multithread perchè quando lancio MessageBox il processo attende l'input dell'utente. Mi chiedo a questo punto se ho usato bene il mutex

PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 16:45
Giovedì, 25/03/2010
ok, allora...

dal momento che il mutex serve per "proteggere" delle risorse condivise (immagino nel tuo caso siano title e message), il suo uso corretto è questo:

threadA:
wait(mutex)
// uso le variabili condivise
release(mutex)

threadB:
wait(mutex)
// uso ...
release(mutex)

entrambi devono chiamare la wait, ed entrambi la release.

La prima wait passa liscia, la seconda viene bloccata (solo un oggetto alla volta può accedere, quindi la prima wait passa indisturbata).
Appena il primo thread chiama la release, la seconda wait viene sbloccata.

ricorda: la prima wait passa SEMPRE liscia. Tutte le successive vengono bloccate (finchè non arriva una release).

Quindi modifica il tuo codice in modo da strutturarlo nel modo che ti ho schematizzato...

attualmente usi in modo scorretto la protezione della risorsa condivisa (c'è solo una wait, che passerà quindi indisturbata).

Ultima modifica effettuata da TheKaneB il 25/03/2010 alle 16:45
PM Quote
Avatar
robrock80 (Normal User)
Pro


Messaggi: 143
Iscritto: 11/12/2006

Segnala al moderatore
Postato alle 16:57
Giovedì, 25/03/2010
Ho risolto in un'altra maniera: ho utilizzato un evento al posto del mutex, ma  a questo punto mi riamene un dubbio: ma la wait sul mutex ha effetto solo sui thread creati con CreateThread o funziona anche per il thread principale del processo?

PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo