我有一个类表示一个有限状态机,它应该在永久循环中运行并检查它是当前状态。在每个状态机器将设置它的下一个状态并且落入idle
状态或做一些工作。我想让另一个线程在工作时改变机器的状态。这将导致竞赛状况如预期。因此,我添加了机器的互斥锁定/解锁打包循环以及允许其他线程更改机器当前状态的公共方法。在C++中处理互斥11
class Robot
{
public:
enum StateType {s1,s2,s3,idle,finish};
void run();
void move();
private:
StateType currentState;
StateType nextState;
StateType previousState;
std::mutex mutal_state;
};
实现:
void Robot::run()
{
this->currentState = s1;
while(true)
{
mutal_state.lock();
switch(currentState)
{
case s1:
// do some useful stuff here...
currentState = idle;
nextState = s3;
break;
case s2:
// do some other useful stuff here...
currentState = idle;
nextState = finish;
break;
case s3:
// again, do some useful things...
currentState = idle;
nextState = s2;
break;
case idle:
// busy waiting...
std::cout << "I'm waiting" << std::endl;
break;
case finish:
std::cout << "Bye" << std::endl;
mutal_state.unlock();
return;
}
mutal_state.unlock();
}
}
且移动方法,它允许其他线程来改变目前的状态:
void Robot::move()
{
mutal_state.lock();
previousState = currentState; // Booommm
currentState = nextState;
mutal_state.unlock();
}
我不能设法找到我做错了!程序崩溃在move()
函数的第一行。在另一方面,GDB不与C++ 11的工作和跟踪代码是不可能的......
UPDATE:
周围打码,我可以看到,问题是在移动功能。当程序试图锁定move()
内的代码片段时,崩溃。例如,如果此举是这样的:
void Robot::move()
{
std::cout << "MOVE IS CALLED" << std::endl;
mutal_state.lock();
//previousState = currentState;
//std::cout << "MOVING" << std::endl;
//currentState = nextState;
mutal_state.unlock();
}
输出是:
s1
I'm waiting
I'm waiting
MOVE IS CALLED1
The program has unexpectedly finished.
但当move
是一个简单的功能,没有做任何事情:
void Robot::move()
{
std::cout << "MOVE IS CALLED" << std::endl;
//mutal_state.lock();
//previousState = currentState;
//std::cout << "MOVING" << std::endl;
//currentState = nextState;
//mutal_state.unlock();
}
程序同时运行。
那么你有没有尝试用打印语句调试? – FrustratedWithFormsDesigner 2012-03-09 19:49:37
@ FrustratedWithFormsDesigner:是的。我知道“爆炸”只发生在某个线程试图调用“move”时。 – 2012-03-09 19:53:14
你使用什么编译器的版本? – ildjarn 2012-03-09 19:53:57