c++ - std::chrono::duration::max() 不适用于线程支持库

标签 c++ multithreading pthreads c++17 c++-chrono

我希望使用 INFINITY、NOTIMEOUT 和值超时的概念创建一个围绕 std::timed_mutex 的包装器,而不是使用不同的库调用(locktry_lock 等)。

我假设如果我使用最大分辨率std::chrono::nanoseconds,其max()持续时间将对应于292年。这足以代表 INFINITY 的概念。

但是我发现如果我使用 STL chrono 库帮助程序类型,即 std::timed_mutex.try_lock_for(std::chrono::nanoseconds::max( )) 当锁被其他线程拥有时立即退出 (false)。下面是一个快速演示应用程序。

#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 时钟有关吗?并且会根据架构的不同而有所不同?

  • 我是不是做了什么蠢事?

最佳答案

std::timed_mutex::try_lock_for 计算一个新的std::chrono::time_point ,根据当前时间点并添加请求的超时持续时间,应在此时触发超时。

对于表示当前时间的任何非零时间点(自纪元以来的时间或自上次重启以来的时间),其分辨率不小于非秒(例如微秒),这样的操作在添加 nanoseconds::max() 时会溢出。 (根据时钟分辨率进行调整),即:

steady_clock::now() + duration_cast<steady_clock::duration>(nanoseconds::max())

溢出就像:

int{1} + std::numeric_limits<int>::max()

溢出,因为 std::chrono::nanoseconds::max()返回[time.traits.duration_values]/p6 :

static constexpr Rep max() noexcept;

Returns: numeric_­limits<Rep>::max().

您的时钟分辨率可能设置为nanoseconds .

关于c++ - std::chrono::duration::max() 不适用于线程支持库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53568626/

相关文章:

c++ - 如何设置 "this"线程的自定义名称?

c# - 如何在C#项目中使用ZK4500指纹扫描仪SDK

c# - 使用任务并行库时线程数增长

c++ - 在运行时向对象添加任意类型

java - Eclipse 挂起一个特定的线程,同时让其他线程运行

java - 划分每个线程在特定范围内使用ID

c++ - 我如何为数组中的元素锁定 MUTEX,而不是为整个数组锁定

linux - 如何使用克隆系统调用分配新的 TLS 区域

c++ - 将一个数组复制到另一个数组而不重复 C++

c++ - 如何使用boost检查文件是否已经打开