boost::threadpool::pool::wait() 不停
boost::threadpool::pool::wait() doesn't stop
我试图用 C++ boost::threadpool
、condition_variable
和 mutex
编写一些任务管理 class。好像程序会停在boost::threadpool::pool::wait()
,但我不知道为什么会这样。
#include <boost/threadpool.hpp>
#include <condition_variable>
#include <iostream>
#include <mutex>
using namespace std;
enum {
Running,
Stopped,
Exiting
};
class C {
private:
int m_iStatus;
mutex m_mtx;
condition_variable m_cond;
boost::threadpool::pool m_tp;
public:
C() : m_iStatus(Stopped), m_tp(8) {}
void Start();
void Exit();
private:
bool Check();
void Dispatcher();
};
bool C::Check()
{
unique_lock<mutex> lk(m_mtx);
if (m_iStatus == Stopped)
m_cond.wait(lk);
if (m_iStatus == Exiting)
return false;
else
return true;
}
void C::Dispatcher()
{
if (!Check())
return;
unique_lock<mutex> lk(m_mtx);
// do something...
cout << "." << endl;
m_tp.schedule(bind(&C::Dispatcher, this));
}
void C::Start()
{
unique_lock<mutex> lk(m_mtx);
m_iStatus = Running;
m_tp.schedule(bind(&C::Dispatcher, this));
}
void C::Exit()
{
unique_lock<mutex> lk(m_mtx);
m_iStatus = Exiting;
m_cond.notify_all(); /* notify those waiting on m_cond */
m_tp.wait(); /* went wrong here */
}
int main()
{
C c;
c.Start();
/* wait for a moment */
Sleep(1000);
/* then call Exit */
c.Exit();
return 0;
}
您在仍然持有互斥锁的情况下进入等待呼叫。这将阻止其他线程完成他们的工作。
在您的特定情况下,m_cond
条件变量正在等待同一个互斥锁,因此只要互斥锁仍在,对 m_cond.wait(lk);
的调用将无法 return被另一个线程占用。
一个解决方案是在通知条件变量和等待线程池完成之间放弃对互斥体的锁定:
{
unique_lock<mutex> lk(m_mtx);
m_iStatus = Exiting;
m_cond.notify_all(); /* notify those waiting on m_cond */
} // lock on m_mtx gets released here
m_tp.wait(); /* this should run fine now */
我试图用 C++ boost::threadpool
、condition_variable
和 mutex
编写一些任务管理 class。好像程序会停在boost::threadpool::pool::wait()
,但我不知道为什么会这样。
#include <boost/threadpool.hpp>
#include <condition_variable>
#include <iostream>
#include <mutex>
using namespace std;
enum {
Running,
Stopped,
Exiting
};
class C {
private:
int m_iStatus;
mutex m_mtx;
condition_variable m_cond;
boost::threadpool::pool m_tp;
public:
C() : m_iStatus(Stopped), m_tp(8) {}
void Start();
void Exit();
private:
bool Check();
void Dispatcher();
};
bool C::Check()
{
unique_lock<mutex> lk(m_mtx);
if (m_iStatus == Stopped)
m_cond.wait(lk);
if (m_iStatus == Exiting)
return false;
else
return true;
}
void C::Dispatcher()
{
if (!Check())
return;
unique_lock<mutex> lk(m_mtx);
// do something...
cout << "." << endl;
m_tp.schedule(bind(&C::Dispatcher, this));
}
void C::Start()
{
unique_lock<mutex> lk(m_mtx);
m_iStatus = Running;
m_tp.schedule(bind(&C::Dispatcher, this));
}
void C::Exit()
{
unique_lock<mutex> lk(m_mtx);
m_iStatus = Exiting;
m_cond.notify_all(); /* notify those waiting on m_cond */
m_tp.wait(); /* went wrong here */
}
int main()
{
C c;
c.Start();
/* wait for a moment */
Sleep(1000);
/* then call Exit */
c.Exit();
return 0;
}
您在仍然持有互斥锁的情况下进入等待呼叫。这将阻止其他线程完成他们的工作。
在您的特定情况下,m_cond
条件变量正在等待同一个互斥锁,因此只要互斥锁仍在,对 m_cond.wait(lk);
的调用将无法 return被另一个线程占用。
一个解决方案是在通知条件变量和等待线程池完成之间放弃对互斥体的锁定:
{
unique_lock<mutex> lk(m_mtx);
m_iStatus = Exiting;
m_cond.notify_all(); /* notify those waiting on m_cond */
} // lock on m_mtx gets released here
m_tp.wait(); /* this should run fine now */