boost.threads - mise en oeuvre du TimedLockable Concept
Bonjour à tous,
J'aimerais pouvoir effectuer une attente lors d'un appel à la méthode Stop().
Cette méthode doit attendre que le thread change d'état après avoir modifier la variable record_enable.
J'aimerais faire cela avec boost.threads... Mais je n'y arrive pas.
J'ai déjà tenté les TimedLockable Concept mais sans succès.
Pourriez-vous m'aider?
Merci d'avance. :)
Voici un petit exemple simple pour illustrer mon problème:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| #include <iomanip>
#include <iostream>
#include <boost/thread/xtime.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
class Recorder
{
typedef enum _REC_STATE {REC_STATE1 = 0, REC_STATE2} REC_STATE;
REC_STATE state;
bool record_enable;
bool quit_thread;
boost::mutex state_mutex;
boost::condition_variable state_cond;
public:
Recorder()
: quit_thread(false)
, record_enable(false)
, state(REC_STATE1)
{
}
~Recorder()
{
}
void QuitThread()
{
{
boost::lock_guard<boost::mutex> lock(state_mutex);
quit_thread = true;
}
state_cond.notify_one();
}
void Start()
{
std::cout << "Start\n";
{
boost::lock_guard<boost::mutex> lock(state_mutex);
record_enable = true;
}
state_cond.notify_one();
}
bool Stop(const unsigned int & _timeout = 0)
{
bool ret = true;
std::cout << "Stop\n";
{
boost::lock_guard<boost::mutex> lock(state_mutex);
record_enable = false;
}
state_cond.notify_one();
if(_timeout)
{
// attendre le passage en REC_STATE1: timeout possible!!!
// ret = true si passage réussi
// ret = false si timeout
}
return ret;
}
void operator()(int arg)
{
boost::unique_lock<boost::mutex> lock(state_mutex);
std::cout << "Recorder Thread begin\n";
bool stop_thread = false;
while(!stop_thread)
{
switch(state)
{
case REC_STATE1: {
if(quit_thread)
{
stop_thread = true;
} else if(record_enable)
{
std::cout << "REC_STATE1 -> REC_STATE2\n";
state = REC_STATE2;
} else
{
std::cout << "REC_STATE1\n";
state_cond.wait(lock);
}
break; }
case REC_STATE2: {
if(quit_thread || !record_enable)
{
std::cout << "REC_STATE2 -> REC_STATE1\n";
state = REC_STATE1;
} else
{
std::cout << "REC_STATE2\n";
state_cond.wait(lock);
}
break; }
}
}
std::cout << "Recorder Thread end\n";
}
};
int main(int argc, char* argv[])
{
Recorder r;
boost::thread th1(boost::bind<void>(boost::ref(r), 42));
Sleep(1000);
r.Start();
Sleep(3000);
if(r.Stop(2000)) // attendre la fin (timeout de 2 sec)
{
std::cout << "Succeed\n";
} else
{
std::cout << "Timeout error\n";
}
Sleep(2000);
r.QuitThread();
th1.join();
return 0;
} |