Skip to content

提问,block_queue.h的超时pop是否存在遗漏任务未执行问题 #320

@rice-cyber

Description

@rice-cyber

原有代码:

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;
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions