提问,block_queue.h的超时pop是否存在遗漏任务未执行问题
原有代码:
bool pop(T &item, int ms_timeout) { struct timespec t = {0, 0}; struct timeval now = {0, 0}; gettimeofday(&now, NULL); m_mutex.lock(); if (m_size <= 0) { t.tv_sec = now.tv_sec + ms_timeout / 1000; t.tv_nsec = (ms_timeout % 1000) * 1000; if (!m_cond.timewait(m_mutex.get(), t)) { m_mutex.unlock(); return false; } } if (m_size <= 0) { m_mutex.unlock(); return false; } m_front = (m_front + 1) % m_max_size; item = m_array[m_front]; m_size--; m_mutex.unlock(); return true; } 这里是否存在问题,检测超时时,可能存在超时,但是实际条件已满足情况,如
- 线程 A 调用 pop ,发现队列为空,开始等待
- 线程 B 调用 push ,添加元素并调用 broadcast
- 线程 A 的 timewait 恰好在 broadcast 之后超时返回
- 线程 A 直接返回 false ,但队列实际上已经有元素了,是否可能在超时唤醒后检查条件是否满足来解决,如: bool pop(T &item,int ms_timeout) { struct timespec t = {0,0}; struct timeval now = {0,0}; gettimeofday(&now,NULL); m_mutex.lock(); while (m_size <= 0) { t.tv_sec = now.tv_sec + ms_timeout / 1000; t.tv_nsec = (ms_timeout % 1000) * 1000; if(!m_cond.timewait(m_mutex.get(), t)){ if (m_size<=0) { // 超时但条件不满足 m_mutex.unlock(); return false; }else { // 超时但条件满足 break; } } } m_front= (m_front + 1) % m_max_size; item = m_array[m_front]; m_size--; m_mutex.unlock(); return true; }
Source: qinguoyi/TinyWebServer