mirror of
https://github.com/boostorg/thread.git
synced 2026-01-22 17:52:18 +00:00
141 lines
3.1 KiB
C++
141 lines
3.1 KiB
C++
// Copyright (C) 2001-2003
|
|
// William E. Kempf
|
|
//
|
|
// Permission to use, copy, modify, distribute and sell this software
|
|
// and its documentation for any purpose is hereby granted without fee,
|
|
// provided that the above copyright notice appear in all copies and
|
|
// that both that copyright notice and this permission notice appear
|
|
// in supporting documentation. William E. Kempf makes no representations
|
|
// about the suitability of this software for any purpose.
|
|
// It is provided "as is" without express or implied warranty.
|
|
|
|
#include <boost/thread/mutex.hpp>
|
|
#include <boost/thread/condition.hpp>
|
|
#include <boost/thread/thread.hpp>
|
|
#include <boost/thread/xtime.hpp>
|
|
#include <iostream>
|
|
|
|
#if defined(BOOST_HAS_WINTHREADS)
|
|
# include <windows.h>
|
|
# include <process.h>
|
|
#endif
|
|
|
|
enum game_state
|
|
{
|
|
START,
|
|
PLAYER_A,
|
|
PLAYER_B,
|
|
GAME_OVER,
|
|
ONE_PLAYER_GONE,
|
|
BOTH_PLAYERS_GONE
|
|
};
|
|
|
|
int state;
|
|
boost::mutex mutex;
|
|
boost::condition cond;
|
|
|
|
char* player_name(int state)
|
|
{
|
|
if (state == PLAYER_A)
|
|
return "PLAYER-A";
|
|
if (state == PLAYER_B)
|
|
return "PLAYER-B";
|
|
throw "bad player";
|
|
return 0;
|
|
}
|
|
|
|
void player(void* param)
|
|
{
|
|
boost::mutex::scoped_lock lock(mutex);
|
|
|
|
int active = (int)param;
|
|
int other = active == PLAYER_A ? PLAYER_B : PLAYER_A;
|
|
|
|
while (state < GAME_OVER)
|
|
{
|
|
std::cout << player_name(active) << ": Play." << std::endl;
|
|
state = other;
|
|
cond.notify_all();
|
|
do
|
|
{
|
|
cond.wait(lock);
|
|
if (state == other)
|
|
{
|
|
std::cout << "---" << player_name(active)
|
|
<< ": Spurious wakeup!" << std::endl;
|
|
}
|
|
} while (state == other);
|
|
}
|
|
|
|
++state;
|
|
std::cout << player_name(active) << ": Gone." << std::endl;
|
|
cond.notify_all();
|
|
}
|
|
|
|
struct thread_adapt
|
|
{
|
|
thread_adapt(void (*func)(void*), void* param)
|
|
: _func(func), _param(param)
|
|
{
|
|
}
|
|
int operator()() const
|
|
{
|
|
_func(_param);
|
|
return 0;
|
|
}
|
|
|
|
void (*_func)(void*);
|
|
void* _param;
|
|
};
|
|
|
|
class thread_adapter
|
|
{
|
|
public:
|
|
thread_adapter(void (*func)(void*), void* param)
|
|
: _func(func), _param(param)
|
|
{
|
|
}
|
|
void operator()() const { _func(_param); }
|
|
private:
|
|
void (*_func)(void*);
|
|
void* _param;
|
|
};
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
state = START;
|
|
|
|
boost::thread thrda(thread_adapter(&player, (void*)PLAYER_A));
|
|
boost::thread thrdb(thread_adapter(&player, (void*)PLAYER_B));
|
|
|
|
boost::xtime xt;
|
|
boost::xtime_get(&xt, boost::TIME_UTC);
|
|
xt.sec += 1;
|
|
boost::thread::sleep(xt);
|
|
{
|
|
boost::mutex::scoped_lock lock(mutex);
|
|
std::cout << "---Noise ON..." << std::endl;
|
|
}
|
|
|
|
for (int i = 0; i < 1000000; ++i)
|
|
cond.notify_all();
|
|
|
|
{
|
|
boost::mutex::scoped_lock lock(mutex);
|
|
std::cout << "---Noise OFF..." << std::endl;
|
|
state = GAME_OVER;
|
|
cond.notify_all();
|
|
do
|
|
{
|
|
cond.wait(lock);
|
|
} while (state != BOTH_PLAYERS_GONE);
|
|
}
|
|
|
|
std::cout << "GAME OVER" << std::endl;
|
|
|
|
thrda.join();
|
|
thrdb.join();
|
|
|
|
return 0;
|
|
}
|