2010-09-08 5 views
1

J'ai un programme en C++ qui exécute un tas de threads pour manipuler les mêmes données. Chacun de ces fils ont un pointeur vers un objet qui est en cours de manipulation, par exemple:Threads C++ et mécanisme de blocage simple?

thread1 et thread2 ont tous deux un pointeur vers Object1
object1-> addSomething() peut être utilisé soit par thread1 ou 2 et se réfèrent à le même objet

Maintenant, ces opérations peuvent poser des problèmes si elles sont effectuées au même moment par les deux threads, donc je veux un mécanisme de blocage simple. Ce que je veux est simplement ceci:

void method() 
{ 
    waitUntilFree() 
    blockForOthers() 
    doSomething() 
    unblock() 
} 

Y at-il un moyen simple de faire cela? Je veux juste bloquer et attendre jusqu'à ce que ce soit gratuit. Cela ne me dérange pas que le fil puisse devoir attendre un moment. Y a-t-il un mécanisme facile à faire? J'utilise Boost pour ces discussions, mais je ne pourrais pas pour la vie de moi trouver un moyen de faire (apparemment) simple bloc-et-attendre chose.

Répondre

1

Utiliser mutex.

Plus d'informations à ce sujet, vous pouvez trouver à http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#SYNCHRONIZATION

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 

void *functionC(); 
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; 
int counter = 0; 

main() 
{ 
    int rc1, rc2; 
    pthread_t thread1, thread2; 

    /* Create independent threads each of which will execute functionC */ 

    if((rc1=pthread_create(&thread1, NULL, &functionC, NULL))) 
    { 
     printf("Thread creation failed: %d\n", rc1); 
    } 

    if((rc2=pthread_create(&thread2, NULL, &functionC, NULL))) 
    { 
     printf("Thread creation failed: %d\n", rc2); 
    } 

    /* Wait till threads are complete before main continues. Unless we */ 
    /* wait we run the risk of executing an exit which will terminate */ 
    /* the process and all threads before the threads have completed. */ 

    pthread_join(thread1, NULL); 
    pthread_join(thread2, NULL); 

    exit(0); 
} 

void *functionC() 
{ 
    pthread_mutex_lock(&mutex1); 
    counter++; 
    printf("Counter value: %d\n",counter); 
    pthread_mutex_unlock(&mutex1); 
} 
+0

C'est C plutôt que C++ (il est int main() en C++), mais un joli petit exemple pour la API POSIX. Peut-être que quelqu'un devrait mentionner que le mutex est synonyme d'exclusion réciproque, tout fil de discussion détenant le verrou exclut les autres de l'acquérir ... –

2

Puisque vous utilisez déjà Boost, vous pouvez utiliser un Boost mutex pour protéger l'accès simultané par plusieurs threads.

Ensuite, utilisez un jointure() sur chaque thread pour attendre qu'il se termine.

// create the mutex where it can be accessed by all threads 
boost::mutex lock; 

// in each thread 
lock.lock(); 
// do something with shared data 
lock.unlock(); 

// for each thread 
thread.join(); // wait for thread to finish 
+0

Pourquoi adhérer si un accès exclusif est souhaité? Dans ce cas, un simple style RAII ['mutex :: scoped_lock'] (http://www.boost.org/doc/libs/1_44_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_types.mutex) est beaucoup mieux adapté. –

+0

Je suis d'accord avec Ferruccio –

+0

@Georg Fritzsche - d'accord. scoped_lock est meilleur. Je voulais juste garder l'exemple simple. En ce qui concerne la jointure, je suppose que c'est une pratique dans laquelle je suis tombé, attendant toujours que les threads se terminent. – Ferruccio

0

Vous recherchez ce que l'on appelle des mutex. Ceux-ci viennent en tant que partie de la bibliothèque de thread. Jetez un oeil à this dr. dobbs article.

5

Comme il est indiqué par Ferruccio vous pouvez utiliser un Mutex comme Boost.Mutex de la même bibliothèque pour la synchronisation:

class X { 
    boost::mutex m_mutex; 
public: 
    void method() { 
     boost::mutex::scoped_lock lock(m_mutex); 
     // ... now locked, do stuff 
    } // mutex automatically unlocked when scoped_lock is destructed 
};