2010-12-07 59 views
0

Je suis en train de mettre en œuvre cet exemple simple de la façon de synchroniser les threads en utilisant la bibliothèque pthread:comportement imprévisible de threads

#include <iostream> 
#include <pthread.h> 

using namespace std ; 

static pthread_mutex_t locker; 
pthread_cond_t cond; 
volatile bool ok=false; 


void *func2(void *data) 
{ 
int i; 
for(i=0;i<100;i++) 
{ 
    pthread_mutex_lock (&locker); 
    cout << "1"; 
    pthread_mutex_unlock(&locker); 
    if(i==10) 
    { 
     ok=true; 
     pthread_cond_signal(&cond); 
    } 

} 

pthread_exit(0); 

    } 

void *fun1(void *data) 
{ 
int i; 
for(i=0;i<100;i++) 
{ 

    if(ok==false){ 
    pthread_cond_wait(&cond, &locker); 
    } 

    pthread_mutex_lock (&locker); 
    cout << "2"; 
    pthread_mutex_unlock(&locker); 
} 

pthread_exit(0); 
    } 




    int main(void) 
    { 


pthread_t thread1, thread2; 
void *retour_thread; 


pthread_mutex_init (&locker, NULL); 
pthread_cond_init(&cond, NULL); 

if(pthread_create (&thread1, NULL, fun1, NULL) < 0) 
{ 
    cout << "problem thread"; 
    exit(1); 
} 
if(pthread_create (&thread2, NULL, func2, NULL) < 0) 
{ 
    cout << "problem thread"; 
    exit(1); 
} 


(void)pthread_join(thread1,&retour_thread); 
(void)pthread_join(thread2,&retour_thread); 

return 0; 
    } 

que dois-je vois func1 attendre que la condition (ok == true) puis processus func2 ... mais ce que je reçois est imprévisible et non synchronisé !!!

toute aide et grâce à advence

Répondre

0

Vous devez acquérir le mutex avant d'appeler pthread_cond_wait, et après le retour pthread_cond_wait, le mutex est réacquis. Votre fun1() devrait ressembler à:

void *fun1(void *data) 
{ 
    int i; 
    for(i=0;i<100;i++) 
    { 
     pthread_mutex_lock (&locker); 
     if(ok==false) 
      pthread_cond_wait(&cond, &locker); 

     cout << "2"; 
     pthread_mutex_unlock(&locker); 
    } 
} 

Mise à jour:

Vous avez une course où func2() peut signaler plus rapidement que fun1() peut consommer. Si vous voulez d'autres sorties "1" et "2", vous avez besoin d'un retour dans les deux sens.

+0

Cela provoque un blocage. Il a également besoin de ne pas acquérir le verrou dans fun2. – Benubird

+0

merci pour la réponse .. mais stil ne peut pas obtenir ce que je veux .... le comportement est aléatoire !!! vous pouvez l'essayer pour voir .... par la façon dont je suis sur Windows – fsidiosidi

+2

@Bububird: pthread_cond_wait libère la serrure atomiquement, c'est pourquoi vous devez passer le verrou – stefaanv

1
  • Règle numéro 1 pour connaître l'état des variables: attendre variable de condition tout en maintenant le verrou (en attendant le verrou sera libéré)
  • Règle numéro 2 pour les variables état : toujours utiliser « en état , attendez condition de variable »(éviter les signaux parasites)
0

Mon expérience avec pthread_cond_wait est qu'il fait alors d'être un peu imprévisible. Il y a quelques choses que vous pouvez essayer cependant. Par exemple, au lieu d'utiliser if (ok == false) essayez d'utiliser while (ok == false), de sorte qu'il répète l'attente si quelque chose le fait revenir tôt (toujours une bonne pratique). Considérez aussi qu'il n'y a pas de cohérence dans la durée d'un thread - par exemple, il est tout à fait possible que thread1 cède immédiatement après le retour de l'attente, ce qui va vous donner des résultats imprévisibles ... Essayez de poster ce qui se passe Nous pouvons donc l'examiner plus en détail.

Aussi, faites ce que janm a dit;)

+0

111111111111111222222222222222222 ..... 2222222222222111.11111111 et c'est aléatoire ... ce que je veux est-ce ... 1 (10 fois) 212121212121..2 (10 fois) .toute la fin – fsidiosidi