实现线程池时使用pthread_cond_t处理任务队列,发现主线程提交任务,而子线程却拿不出任务。

文章讲述了作者在实现线程池时遇到的问题,即主线程添加任务后子线程未能正确获取。通过分析发现是由于信号发出过早导致的。作者提供了两种解决方案,包括使用sem_t替代和考虑添加标识位,同时寻求更高效的方法。
摘要由CSDN通过智能技术生成

        在自己实现线程池的时候,对于主线程添加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;
​
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值