|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
[Linux C] Emulare WaitForSingleObject con timeout
Ho provato ad emulare la WaitForSingleObject di Windows usando le pThread, ma ci sono riuscito solo in parte.
Il mio obiettivo è quello di bloccare un thread in attesa di un evento, se però la condizione di wait per un qualche motivo viene impostata dopo il signal (in debug avviene praticamente sempre) ottengo un fallimento per timeout, mentre in Windows viene riconosciuto l'evento come già settato e la WaitForSingleObject ritorna subito. Questo è il codice che ho usato: Codice:
class Event { public: Event() { #ifdef WIN32 event = CreateEvent(NULL,false,false,NULL); #else pthread_cond_init (&event, NULL); pthread_mutex_init(&mutex, NULL); #endif } ~Event() { #ifdef WIN32 CloseHandle(event); #else pthread_mutex_destroy(&mutex); pthread_cond_destroy(&event); #endif } void SetEvent() { #ifdef WIN32 ::SetEvent(event); #else pthread_cond_signal(&event); #endif } void ResetEvent() { #ifdef WIN32 ::ResetEvent(event); #else pthread_cond_signal(&event); #endif } bool Wait() { #ifdef WIN32 return WaitForSingleObject(event,INFINITE) == WAIT_OBJECT_0; #else pthread_mutex_lock(&mutex); int rc = pthread_cond_wait(&event, &mutex); pthread_mutex_unlock(&mutex); return rc == 0; #endif } bool Wait(int milliseconds) { #ifdef WIN32 return WaitForSingleObject(event,milliseconds) == WAIT_OBJECT_0; #else struct timeval now; struct timespec timeout; gettimeofday(&now, NULL); timeout.tv_sec = now.tv_sec + milliseconds/1000; timeout.tv_nsec = now.tv_usec * 1000; bool done = false, success = false; int rc = pthread_mutex_lock(&mutex); if (rc) /* an error has occurred */ return false; while (!done) { rc = pthread_cond_timedwait(&event,&mutex,&timeout); switch (rc) { case 0: success = true; done = true; break; default: if (rc == ETIMEDOUT) done = true; break; } } pthread_mutex_unlock(&mutex); return success; #endif } private: #ifdef WIN32 HANDLE event; #else pthread_cond_t event; pthread_mutex_t mutex; #endif }; ![]() Un altra domanda ma se volessi attendere sulla pthread_cond_timedwait per 1500 millisecondi devo per forza aggiungere 1 al campo tv_sec e 5e8 a tv_nsec? Non c'è un modo per aggiungere direttamente il valore a tv_nsec? Quando ho provato ad aggiungere 15e8 al campo tv_nsec non ho mai raggiunto il timeout. |
![]() |
![]() |
![]() |
#2 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
fino a qualche mese fa anche io stavo a combattere con questioni del genere, ma ho fatto in maniera molto diversa: non ho cercato più di tanto di uniformare il codice Linux con quello Win32. nel caso specifico degli eventi, portando su Linux ho parzialmente ristrutturato e utilizzato i pthread signals (alla fine IMHO è più facile fare così che non sbattersi ad inventarsi meccanismi di emulazione).
|
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Vorrei capire come fare in modo che una condizione di wait possa terminare con successo se per caso il signal è arrivato prima. Su Windows questo avviene automaticamente senza problemi, su Linux non sono ancora riuscito ad ottenerlo. Al momento il codice che ho scritto non mi pare dare alcun problema, però è impossibile debuggare proprio per il fatto che in debug finisce che arriva prima il signal e poi il wait. |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 13:57.