我希望围绕std::timed_mutex
创建一个具有INFINITY,NOTIMEOUT和值超时的概念的包装器,而不是使用不同的库调用(lock
,try_lock
等)。
我假设如果使用最大分辨率std::chrono::nanoseconds
,则其max()
持续时间将对应292年。足以代表INFINITY的概念。
但是,我发现如果使用STL chrono
库帮助程序类型是行不通的,即std::timed_mutex.try_lock_for(std::chrono::nanoseconds::max())
在锁被其他线程拥有时立即退出(false
)。 Bellow是一个快速演示应用程序。
#include <cstdlib>
#include <ratio>
#include <chrono>
#include <mutex>
#include <thread>
#include <iostream>
#define STR_ME(expr_) #expr_
template <typename Duration>
void check_infinity(const char *name,const Duration &timeout)
{
std::timed_mutex tmd_mx;
tmd_mx.lock(); //mutex is locked by std::this_thread
auto thread_f=[&](const char *name,Duration timeout)
{
if (!tmd_mx.try_lock_for(timeout))
std::cout << name << " : TIMEOUT!!" << std::endl;
else
std::cout << "Green light..." << std::endl;
};
std::thread t{thread_f,name,timeout};
std::this_thread::sleep_for(std::chrono::seconds(2)); //Ensures thread "t" runs.
t.join();
std::cout << "Houston??" << std::endl; //Shouldn't reach this point ever.
}
int main(int argc, char** argv)
{
check_infinity(STR_ME(std::chrono::nanoseconds::max()),std::chrono::nanoseconds::max()); //Fails
//Every other STL chrono::durations fail.
using my_nanoseconds = std::chrono::duration<unsigned int,std::nano>; //STL uses long.
using my_seconds = std::chrono::duration<unsigned int>;
check_infinity(STR_ME(my_nanoseconds::max()),my_nanoseconds::max()); // Fails
check_infinity(STR_ME(my_seconds::max()),my_seconds::max()); // Works !!
return EXIT_FAILURE;
}
对于该测试,我在ubuntu中使用了pthread库。
我的问题是:
这是pthread库的“限制”吗?毕竟max()
的持续时间对应于rep
的最大值。
此最大值在某处定义吗?
此最大值与CPU时钟有关吗?并可能因架构而异?
答案 0 :(得分:2)
std::timed_mutex::try_lock_for
根据当前时间点并添加请求的超时时间,计算出一个新的std::chrono::time_point
,在该时间应触发超时。
对于表示当前时间(从纪元开始的时间或自上次重新启动以来的时间)的任何非零时间点,其分辨率均不少于毫秒(例如,微秒),当添加{{1}时,此类操作会溢出}(已调整为时钟的分辨率),即:
nanoseconds::max()
溢出就像:
steady_clock::now() + duration_cast<steady_clock::duration>(nanoseconds::max())
溢出,因为int{1} + std::numeric_limits<int>::max()
返回[time.traits.duration_values]/p6:
std::chrono::nanoseconds::max()
返回:
static constexpr Rep max() noexcept;
。
您的时钟分辨率可能设置为numeric_limits<Rep>::max()
。