如果持续时间太大,为什么 std::condition_variable::wait_for() return 会超时?
Why does std::condition_variable::wait_for() return with timeout if duration too large?
在 g++ 11.2.1 下出现了以下行为。如果超时变量太大,std::condition_variable
wait_for
方法 returns 立即。特别是在下面的程序中,如果 num_years==1
,则程序会按预期挂起等待(大概 1 年),但如果变量 num_years==1000
,则程序会立即 returns。
为什么会这样?这是g ++中的错误吗?还有一个相关的问题,你如何让 cv.wait_for()
无限期地等待,而不是猜测一个大的超时值?
// This is 'cv_wait.cc' compile with:
//
// g++ -o cv_wait -std=c++2a cv_wait.cc
//
// An example showing that wait_for() returns immediately with a timeout
// return value if the duration variable is "too large".
//
#include <iostream>
#include <condition_variable>
#include <chrono>
int main(int argc, char **argv)
{
std::condition_variable cv;
std::mutex cv_m;
// If num_years is "too large", e.g. 1000, then cv.wait_for()
// returns immediately with a timeout condition!
int num_years = 1; // If 1000 then cv.wait_for() returns immediately!
std::chrono::seconds timeout((uint64_t)3600 * 24 * 365 * num_years);
std::unique_lock<std::mutex> lock(cv_m);
if (cv.wait_for(lock, timeout, [] { return false; }))
std::cerr << "No timeout!\n";
else
std::cerr << "Timeout!\n";
}
这是 condition_variable::wait_for
的一个溢出错误。在内部它正在等待使用 steady_clock
计数 nanoseconds
。该时钟在 +/-292 年时溢出。因此,当 1000 年转换为 nanoseconds
时,它会溢出。
这看起来像是标准错误,而不是实现错误:http://eel.is/c++draft/thread.condition#condvar-24
实现应该检查这种类型的溢出,如果发现,只等待它能够等待的最长时间。
在 g++ 11.2.1 下出现了以下行为。如果超时变量太大,std::condition_variable
wait_for
方法 returns 立即。特别是在下面的程序中,如果 num_years==1
,则程序会按预期挂起等待(大概 1 年),但如果变量 num_years==1000
,则程序会立即 returns。
为什么会这样?这是g ++中的错误吗?还有一个相关的问题,你如何让 cv.wait_for()
无限期地等待,而不是猜测一个大的超时值?
// This is 'cv_wait.cc' compile with:
//
// g++ -o cv_wait -std=c++2a cv_wait.cc
//
// An example showing that wait_for() returns immediately with a timeout
// return value if the duration variable is "too large".
//
#include <iostream>
#include <condition_variable>
#include <chrono>
int main(int argc, char **argv)
{
std::condition_variable cv;
std::mutex cv_m;
// If num_years is "too large", e.g. 1000, then cv.wait_for()
// returns immediately with a timeout condition!
int num_years = 1; // If 1000 then cv.wait_for() returns immediately!
std::chrono::seconds timeout((uint64_t)3600 * 24 * 365 * num_years);
std::unique_lock<std::mutex> lock(cv_m);
if (cv.wait_for(lock, timeout, [] { return false; }))
std::cerr << "No timeout!\n";
else
std::cerr << "Timeout!\n";
}
这是 condition_variable::wait_for
的一个溢出错误。在内部它正在等待使用 steady_clock
计数 nanoseconds
。该时钟在 +/-292 年时溢出。因此,当 1000 年转换为 nanoseconds
时,它会溢出。
这看起来像是标准错误,而不是实现错误:http://eel.is/c++draft/thread.condition#condvar-24
实现应该检查这种类型的溢出,如果发现,只等待它能够等待的最长时间。