Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

C++11 - gcc conditional_var problem

5 réponses
Avatar
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 << "Ready...Set...Go!" << 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;
}

5 réponses

Avatar
didier.cassirame
Ca devrait marcher avec:

LastPlayingPlayerCondVar.notify_all();

à la place de notify_one.
Avatar
didier.cassirame
Ca devrait marcher avec:

LastPlayingPlayerCondVar.notify_all();

à la place de notify_one.
Avatar
didier.cassirame
Ca devrait marcher avec:

LastPlayingPlayerCondVar.notify_all();

à la place de notify_one.
Avatar
David FLEURY
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...
Avatar
David FLEURY
// ---------------------------------------------------------------------
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"