2016-03-27 1 views
0

Je suis en train d'essayer la programmation multicœur, pour mettre en œuvre Mutex sémaphore pour: Initialisation; Demander la propriété Libérer la propriété; Essayez la propriété Destruction .Comment fonctionne le sémaphore mutex?

J'ai créé 3 threads. Chaque thread fonctionne sur une variable globale Answer. 9 fois sur 10, les threads s'exécutent séquentiellement. Mais parfois, le thread 3 ne s'est pas exécuté. Est-ce que le second thread mutex n'a pas été libéré?

Voici mon code: thread_tasks.cc

void *task1(void *X) 
{ 

    int MValue = pthread_mutex_init(&Mutex,NULL); //Initialization 
    pthread_mutex_lock(&Mutex); //Request ownership 
    Answer = Answer * 32; //critical section 
    pthread_mutex_unlock(&Mutex); //Release ownership 
    flag1=1; 
    cout << "\nthread A Answer = " << Answer << endl; 
    cout<<"\nthread 1 executed successfully"; 
} 

void *task2(void *X) 
{ 
    if(flag1==1) 
{ 
    int RC = pthread_mutex_trylock(&Mutex); //Try ownership 
    cout<<"\nRC: "<<RC; 
    Answer = Answer/2; 
    flag2=1; 
    cout<<"\nthread 2 executed successfully"; 
    pthread_mutex_unlock(&Mutex); //Release ownership 
    pthread_mutex_destroy(&Mutex); //Destruction 

} 
} 



void *task3(void *X) 
{ 
    Answer = Answer+5; 
    cout<<"\nthread 3 executed successfully"; 
} 

fichier d'en-tête: thread_tasks.h

using namespace std; 
#include <iostream> 
#include <pthread.h> 

void *task1(void *X); 
void *task2(void *X); 
void *task3(void *X); 

mutex_example.cpp

int Answer = 10; 
int flag1 = 0; 
int flag2 = 0; 
int main(int argc, char *argv[]) 
{ 

pthread_t ThreadA, ThreadB, ThreadC; 

cout << "Answer = " << Answer << endl; 
pthread_create(&ThreadA,NULL,task1,NULL); 
pthread_create(&ThreadB,NULL,task2,NULL); 
pthread_create(&ThreadC,NULL,task3,NULL); 
pthread_join(ThreadA,NULL); 
pthread_join(ThreadB,NULL); 
pthread_join(ThreadC,NULL); 

cout << "Answer = " << Answer << endl; 

return(0); 
} 
+1

Vous avez une course de données sur 'flag1' et' flag2'. Cela n'aide pas que vous les écrivez sous la protection d'un mutex, quand vous les lisez sans. –

+0

En outre, la course de données mise à part, votre code ne garantit pas que les threads s'exécutent séquentiellement. Au lieu de cela, il s'assure que, si un thread 'N + 1' passe devant le thread 'N', il ne fait rien, ignorant tout traitement substantiel. Vous n'avez aucune logique qui amène le thread 'N + 1' à attendre que le thread' N' se termine. –

+0

@IgorTandetnik Si je n'utilise pas de drapeaux, la réponse devient parfois 162 car le thread 3 s'exécute avant le thread 2 quelle devrait être la logique de l'exécution séquentielle? – daemon7osh

Répondre

0

Résolu le problème: Utilisé thread_1done et thread_2done pour maintenir la séquence.

void *task1(void *X) 
    { 
     int MValue = pthread_mutex_init(&Mutex,NULL); //Initialization 
     pthread_mutex_lock(&Mutex); //Request ownership 
     Answer = Answer * 32; //critical section 
     pthread_mutex_unlock(&Mutex); //Release ownership 
     thread_1done=1; 
     cout << "\nthread A Answer = " << Answer << endl; 
     cout<<"thread 1 executed successfully"<<endl; 
    } 


    void *task2(void *X) 
    { 
     while(1) 
      if(thread_1done==1) 
      { 
       int RC = pthread_mutex_trylock(&Mutex); //Try ownership 
       Answer = Answer/2; 
       pthread_mutex_unlock(&Mutex); 
       thread_2done=1; 
       cout << "\nthread B Answer = " << Answer << endl; 
       cout<<"thread 2 executed successfully"<<endl; 
       break; 
      } 
    } 



    void *task3(void *X) 
    { 
     while(1) 
      if (thread_2done==1 && thread_1done == 1) 
      { 
       int RC = pthread_mutex_trylock(&Mutex); //Try ownership 
       Answer = Answer+5; 
       pthread_mutex_unlock(&Mutex); 
       pthread_mutex_destroy(&Mutex); //Destruction 
       cout << "\nthread C Answer = " << Answer << endl; 
       cout<<"thread 3 executed successfully"<<endl; 
       break; 
      } 
    } 
0

la véritable exécution de la fonction fil 3 - TASK3 need flag2 == 1, qui à ce moment-là peut-être thread 2 n'a pas terminé la tâche de réinitialisation flag2. Donc la tâche 3 n'est probablement pas dans le bloc si.

+0

Y a-t-il un moyen de résoudre ce problème? – daemon7osh