boost::threadpool::pool::wait() 不会停止
我试图用 C++ boost::threadpool
、condition_variable
和 mutex
编写一些任务管理类。看起来程序将停止在 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;
}
I was trying to write some Task-Management class with C++ boost::threadpool
, condition_variable
and mutex
. It seems the program will stop at boost::threadpool::pool::wait()
, but I don't know why this happens.
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在仍持有互斥锁的情况下进入等待调用。这将阻止其他线程完成其工作。
在您的特定情况下,
m_cond
条件变量正在等待同一个互斥体,因此对m_cond.wait(lk);
的调用将无法返回,只要互斥锁仍由另一个线程持有。解决此问题的一种方法是在通知条件变量和等待线程池完成之间放弃互斥锁:
You enter the wait call while still holding the mutex. This will prevent other thread's from completing their work.
In your particular case, the
m_cond
condition variable is waiting on that same mutex, so the call tom_cond.wait(lk);
will be unable to return as long as the mutex is still being held by the other thread.One solution to this would be to relinquish the lock on the mutex between notifying the condition variable and waiting for the thread pool to complete: