C++11 - gcc conditional_var problem

Le
David FLEURY
Bonjour,
j'ai fait un petit exercice en C++11.
But : Créer 2 threads, qui prennent la main chacun leur tour

Ca fonctionne sous VS 2012, gcc 4.7.2.
Ca reste bloqué sous gcc 4.8.0. Le dernier "joueur" ne reçoit pas un
signal. En remplaçant la lambda, ça bloque aussi sous gcc 4.4


Auriez-vous une idée de mon erreur ?

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

//
const int OnePlayerGameMaxDuration = 3;

//
std::thread::id LastPlayingPlayer;
std::mutex LastPlayingPlayerMutex;
std::condition_variable LastPlayingPlayerCondVar;

//
bool IsLastPlayer(const std::thread::id& id)
{
return (LastPlayingPlayer == id);
}

//
void SetLastPlayer(const std::thread::id& id)
{
LastPlayingPlayer = id;
}

//
void Player(const std::string& playerName)
{
std::thread::id playerId = std::this_thread::get_id();

for (int i = 0; i < OnePlayerGameMaxDuration; ++i)
{
std::unique_lock<std::mutex> lock(LastPlayingPlayerMutex);
while(IsLastPlayer(playerId))
LastPlayingPlayerCondVar.wait(lock); // Wait someone else

std::cout << playerName << std::endl;

SetLastPlayer(playerId);

// Notify another player, the play is done
LastPlayingPlayerCondVar.notify_one();
}
}

// --
int main()
{
// Game started
std::cout << "ReadySetGo!" << std::endl;

// Start 2 players : Ping! and Pong!
std::thread player1([] { Player("Ping!"); });
std::thread player2([] { Player("Pong!"); });

// Wait for the players to finish
player1.join();
player2.join();

// Game finished
std::cout << "Done!" << std::endl;
}
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
didier.cassirame
Le #25366602
Ca devrait marcher avec:

LastPlayingPlayerCondVar.notify_all();

à la place de notify_one.
didier.cassirame
Le #25366592
Ca devrait marcher avec:

LastPlayingPlayerCondVar.notify_all();

à la place de notify_one.
didier.cassirame
Le #25366582
Ca devrait marcher avec:

LastPlayingPlayerCondVar.notify_all();

à la place de notify_one.
David FLEURY
Le #25366762
Le 27/04/2013 00:57, a écrit :
Ca devrait marcher avec:

LastPlayingPlayerCondVar.notify_all();

à la place de notify_one.




En fait, c'était plus un problème de compile/link de gcc.
Il faut mettre -pthread sinon le comportement ne semble pas stable.
En tout cas, l'utilisation de cette option a réglé mes problèmes, même
si je ne vois pas pourquoi à mon niveau, je dois le spécifier...
David FLEURY
Le #25414172
// ---------------------------------------------------------------------
void Player(const std::string& playerName)
{
std::thread::id playerId = std::this_thread::get_id();

for (int i = 0; i < OnePlayerGameMaxDuration; ++i)
{
std::unique_lock<std::mutex> lock(LastPlayingPlayerMutex);
while(IsLastPlayer(playerId))
LastPlayingPlayerCondVar.wait(lock); // Wait someone else




Ici, la boucle while doit être remplacée par :

LastPlayingPlayerCondVar.wait(lock,[=] { return
!IsLastPlayer(playerId); }); // Wait someone else

pour cause de "spurious wakeup"
Publicité
Poster une réponse
Anonyme