2013-06-10 1 views
0

Je suis novice en programmation Windows C++. S'il vous plaît voir le code ci-dessous où je veux synchroniser les deux threads. Le premier thread devrait imprimer "Bonjour" puis passer le contrôle/événement au deuxième thread. Vous ne savez pas comment le faire. A partir de maintenant, j'utilise le sommeil (1000). Mais si je n'utilise pas le sommeil, il en résulte un comportement indéfini. S'il vous plaît aider ...Synchronisez deux threads en passant des événements entre eux

#include <windows.h> 
#include <process.h> 
#include <iostream> 

void thread1(void*); 
void thread2(void*); 

int main(int argc, char **argv) { 
    _beginthread(&thread1,0,(void*)0); 
    _beginthread(&thread2,0,(void*)0); 
    Sleep(1000); 
} 

void thread1(void*) 
{ 
    std::cout<<"Hello "<<std::endl; 
} 
void thread2(void*) 
{ 
    std::cout<<"World"<<std::endl; 
} 
+0

Si vous voulez que les choses s'exécutent dans l'ordre, pourquoi ne pas les exécuter sur le même thread, l'une après l'autre? –

+0

Non ... c'est juste pour ma compréhension de la synchronisation de fil .... –

+3

La réponse à cette question pourrait éventuellement prendre un livre entier. Vous demandez fondamentalement "enseignez-moi multithreading." –

Répondre

5

Le problème est que la question que vous posez n'a vraiment aucun sens. Plusieurs threads sont conçus pour exécuter en même temps et vous essayez de jouer à un jeu de passer la balle d'un fil à l'autre pour obtenir un comportement sérialisé séquentiel. C'est comme prendre un outil vraiment compliqué et demander comment il résout ce qui est normalement une question vraiment facile.

Cependant, le multithreading est un sujet très important à apprendre donc j'essaierai de répondre à ce dont vous avez besoin au mieux de mes capacités.

Tout d'abord, je recommande d'utiliser les nouvelles fonctions et bibliothèques C++ 11 standard. Pour les fenêtres, vous pouvez télécharger Visual Studio 2012 Express Edition pour jouer avec. Avec ceci, vous pouvez utiliser std :: thread, std :: mutex et beaucoup [mais pas tous] les autres goodies C++ 11 (comme std :: condition_variable).

Pour résoudre votre problème vous avez vraiment besoin d'une variable de condition. Cela vous permet de signaler à un autre thread que quelque chose est prêt pour eux:

#include <iostream> 
#include <mutex> 
#include <atomic> 
#include <condition_variable> 
#include <thread> 

static std::atomic<bool> ready; 
static std::mutex lock; 
static std::condition_variable cv; 

// ThreadOne immediately prints Hello then 'notifies' the condition variable 
void ThreadOne() 
{ 
    std::cout << "Hello "; 
    ready = true; 
    cv.notify_one(); 
} 

// ThreadTwo waits for someone to 'notify' the condition variable then prints 'World' 
// Note: The 'cv.wait' must be in a loop as spurious wake-ups for condition_variables are allowed 
void ThreadTwo() 
{ 
    while(true) 
    { 
     std::unique_lock<std::mutex> stackLock(lock); 
     cv.wait(stackLock); 
     if(ready) break; 
    } 
    std::cout << "World!" << std::endl; 
} 

// Main just kicks off two 'std::thread's. We must wait for both those threads 
// to finish before we can return from main. 'join' does this - its the std 
// equivalent of calling 'WaitForSingleObject' on the thread handle. its necessary 
// to call join as the standard says so - but the underlying reason is that 
// when main returns global destructors will start running. If your thread is also 
// running at this critical time then it will possibly access global objects which 
// are destructing or have destructed which is *bad* 
int main(int argc, char **argv) 
{ 
    std::thread t1([](){ThreadOne();}); 
    std::thread t2([](){ThreadTwo();}); 
    t1.join(); 
    t2.join(); 
} 
+0

Mieux, mais vous devez * vraiment * expliquer 'join'. –

+0

Merci, maintenant je peux +1. –

+0

@SoumyajitRoy: S'il vous plaît assurez-vous de lire les commentaires * code * profondément *. Ils sont essentiels pour comprendre pourquoi ce code fonctionne. –

0

Voici la version simplifiée pour gérer votre situation.

Vous créez 2 threads pour appeler 2 fonctions différentes. Idéalement, la synchronisation des threads est utilisée pour sérialiser le même code entre les threads mais dans votre cas ce n'est pas le cas. Vous essayez de sérialiser 2 threads qui ne sont aucunement liés les uns aux autres. N'importe comment vous pouvez attendre que chaque thread se termine en ne faisant pas d'appel asynchrone.

#include <windows.h> 
#include <process.h> 
#include <iostream> 
#include<mutex> 

using namespace std; 

void thread1(void*); 
void thread2(void*); 

int main(int argc, char **argv) { 

    HANDLE h1 = (HANDLE)_beginthread(&thread1,0,(void*)0); 
    WaitForSingleObject(h1,INFINITE); 

    HANDLE h2 = (HANDLE)_beginthread(&thread2,0,(void*)0); 
    WaitForSingleObject(h2,INFINITE); 

} 

void thread1(void*) 
{ 
    std::cout<<"Hello "<<std::endl; 
} 
void thread2(void*) 
{ 
    std::cout<<"World"<<std::endl; 
} 

Vous pouvez grouper à la fois beginthread en fonction unique et appeler cette fonction dans while si vous souhaitez imprimer plusieurs fois.

void fun() 
    {  
    HANDLE h1 = (HANDLE)_beginthread(&thread1,0,(void*)0); 
    WaitForSingleObject(h1,INFINITE); 

    HANDLE h2 = (HANDLE)_beginthread(&thread2,0,(void*)0); 
    WaitForSingleObject(h2,INFINITE);  
} 
+0

Oui ... vous avez raison ... et si je veux une impression comme" Bonjour le monde Bonjour le monde Bonjour tout le monde "? –

+0

oui ... ça marche! –

+0

@SoumyajitRoy bienvenue ... – shivakumar

Questions connexes