在自己实现线程池的时候,对于主线程添加work和子线程拿取work的时候,发现在维持任务队列使用cond,实际中发现主线程提交任务成功而子线程并没有从队列中拿出任务来处理。
通过条件变量pthread_cond_wait()和pthread_cond_signal()详解 - CTHON - 博客园 (cnblogs.com)寻找了问题所在,同时也通过在cond.wait()前和cond.signal()打印信息来验证,发现其实是子线程还没wait的时候,主线程已经发出信号了,从而导致无法完成主线程生产后子线程拿到任务,导致线程池的编写错误。
对于此问题:
1.用sem_t 替换pthread_cond_t,此方法能解决此问题。
2.我认为可以添加一个标识位来判断此时是否已经有子线程在等待了,但还是有些不美观和效率影响,所以发出这篇博客希望能获得不使用sem的更好解决方案。
以下是我的代码:
int pthreadPool::__postWork(func fc)
{
lock_.lock();
if (q_work.size() >= max_request_)
{
fprintf(stderr, "queue work size bigger than max_request \n");
lock_.unlock();
return false;
}
q_work.push_back(fc);
lock_.unlock();
cond_.signal();
return true;
}
func pthreadPool::__popWork()
{
cond_.wait(&lock_);
lock_.lock();
if (q_work.empty())
{
lock_.unlock();
return nullptr;
}
func fc = q_work.front();
q_work.pop_front();
lock_.unlock();
return fc;
}