-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Open
Description
原有代码:
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;
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels