How do I deal with the system clock changing while waiting on a std::condition_variable?

后端 未结 4 1923
抹茶落季
抹茶落季 2020-12-15 06:01

I\'m trying to implement some cross-platform code in C++11. Part of this code implements a semaphore object using a std::condition_variable. When I need to do a timed wait

4条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-15 06:21

    I encountered the same problem. A colleague of mine gave me a tip to use certain C functions from instead and it worked out wonderfully for me.

    As an example, I had:

    std::mutex m_dataAccessMutex;
    std::condition_variable m_dataAvailableCondition;
    

    with its standard usage:

    std::unique_lock _(m_dataAccessMutex);
    // ...
    m_dataAvailableCondition.notify_all();
    // ...
    m_dataAvailableCondition.wait_for(...); 
    

    The above can be replaced by using pthread_mutex_t and pthread_cond_t. The advantage is that you can specify the clock to be monotonic. Brief usage example:

    #include 
    
    // Declare the necessary variables
    pthread_mutex_t m_mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_condattr_t m_attr;
    pthread_cond_t m_cond;
    
    // Set clock to monotonic
    pthread_condattr_init(&m_attr);
    pthread_condattr_setclock(&m_attr, CLOCK_MONOTONIC);
    pthread_cond_init(&m_cond, &m_attr); 
    
    // Wait on data
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    ts.tv_sec += timout_in_seconds; 
    pthread_mutex_lock(&m_mutex);
    int rc = pthread_cond_timedwait(&m_cond, &m_mutex, &ts);
    if (rc != ETIMEDOUT)
        ; // do things with data
    else 
        ; // error: timeout
    // ...
    pthread_mutex_unlock(&m_mutex); // have to do it manually to unlock
    // ...
    
    // Notify the data is ready
    pthread_cond_broadcast(&m_cond);
    

提交回复
热议问题