gpt4 book ai didi

c++11 - std::condition_variable::wait_for 在给定 std::chrono::duration::max 时立即退出

转载 作者:行者123 更新时间:2023-12-04 20:03:33 26 4
gpt4 key购买 nike

我在 std::queue 周围有一个包装器使用 C++11 语义允许并发访问。 std::queuestd::mutex 保护.当一个项目被插入队列时,一个 std::condition_variable通过调用 notify_one 获得通知.

从队列中弹出一个项目有两种方法。使用 std::condition_variable::wait(),一种方法将无限期地阻塞,直到一个项目被推送到队列中。 .第二个将阻塞由 std::chrono::duration 给定的时间量单位使用 std::condition_variable::wait_for() :

template <typename T> template <typename Rep, typename Period>
void ConcurrentQueue<T>::Pop(T &item, std::chrono::duration<Rep, Period> waitTime)
{
std::cv_status cvStatus = std::cv_status::no_timeout;
std::unique_lock<std::mutex> lock(m_queueMutex);

while (m_queue.empty() && (cvStatus == std::cv_status::no_timeout))
{
cvStatus = m_pushCondition.wait_for(lock, waitTime);
}

if (cvStatus == std::cv_status::no_timeout)
{
item = std::move(m_queue.front());
m_queue.pop();
}
}

当我在空队列上像这样调用这个方法时:
ConcurrentQueue<int> intQueue;

int value = 0;
std::chrono::seconds waitTime(12);

intQueue.Pop(value, waitTime);

然后 12 秒后,对 Pop() 的调用将退出。但是如果 waitTime 设置为 std::chrono::seconds::max() ,然后对 Pop() 的调用将立即退出。毫秒::max() 和 hours::max() 也会发生同样的情况。但是, days::max() 按预期工作(不会立即退出)。

是什么导致 seconds::max() 立即退出?

这是用mingw64编译的:
g++ --version

g++ (rev5, Built by MinGW-W64 project) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

最佳答案

首先,定时等待应该是 wait_until(lock, std::chrono::steady_clock::now() + waitTime); ,不是 wait_for因为循环现在将简单地重复等待多次,直到最终条件( m_queue.empty() )变为真。重复也可能由虚假唤醒引起。

使用谓词等待方法修复该部分代码:

template <typename Rep, typename Period>
bool pop(std::chrono::duration<Rep, Period> waitTime, int& popped)
{
std::unique_lock<std::mutex> lock(m_queueMutex);

if (m_pushCondition.wait_for(lock, waitTime, [] { return !m_queue.empty(); }))
{
popped = m_queue.back();
m_queue.pop_back();
return true;
} else
{
return false;
}
}

在我的实现中至少 seconds::max() yield 0x7fffffffffffffff
第 30.5.1 条第 26 条规定:

Effects: as if

 return wait_until(lock, chrono::steady_clock::now() + rel_time);


正在做
auto time = steady_clock::now() + seconds::max();
std::cout << std::dec << duration_cast<seconds>(time.time_since_epoch()).count() << "\n";

在我的系统上,打印
265521

使用 date --date='@265521' --rfc-822告诉我那是 Sun, 04 Jan 1970 02:45:21 +0100
GCC 和 Clang 有一个环绕错误,见下文

测试员

Live On Coliru
#include <thread>
#include <condition_variable>
#include <iostream>
#include <deque>
#include <chrono>
#include <iomanip>

std::mutex m_queueMutex;
std::condition_variable m_pushCondition;

std::deque<int> m_queue;

template <typename Rep, typename Period>
bool pop(std::chrono::duration<Rep, Period> waitTime, int& popped)
{
std::unique_lock<std::mutex> lock(m_queueMutex);

if (m_pushCondition.wait_for(lock, waitTime, [] { return !m_queue.empty(); }))
{
popped = m_queue.back();
m_queue.pop_back();
return true;
} else
{
return false;
}
}

int main()
{
int data;
using namespace std::chrono;

pop(seconds(2) , data);

std::cout << std::hex << std::showbase << seconds::max().count() << "\n";
auto time = steady_clock::now() + seconds::max();
std::cout << std::dec << duration_cast<seconds>(time.time_since_epoch()).count() << "\n";
pop(seconds::max(), data);
}

关于c++11 - std::condition_variable::wait_for 在给定 std::chrono::duration::max 时立即退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27726818/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com