在“条件变量” wait_for()notify()机制中使用CLOCK_MONOTONIC类型

时间:2019-01-23 08:47:45

标签: linux c++11 condition-variable

我正在使用在ARM(不是Intel处理器)上运行的代码。从以下位置运行c ++ 11代码示例(CODE A):http://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/以测试wait_for()机制。这是行不通的-看起来wait_for()没有等待。在英特尔工作正常。经过研究并直接使用pthread库并设置MONOTONIC_CLOCK定义,解决了该问题(代码B)。 (在ARM上运行不是问题)

我的问题是: 如何强制C ++ 11 API wait_for()与MONOTONIC_CLOCK一起使用?

实际上,我希望保留“ CODE A”,但要使用MONOTONIC_CLOCK的支持或设置。 谢谢

代码A

// condition_variable::wait_for example
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <chrono>             // std::chrono::seconds
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status

std::condition_variable cv;

int value;

void read_value() {
  std::cin >> value;
  cv.notify_one();
}

int main ()
{
  std::cout << "Please, enter an integer (I'll be printing dots): \n";
  std::thread th (read_value);

  std::mutex mtx;
  std::unique_lock<std::mutex> lck(mtx);
  while 
(cv.wait_for(lck,std::chrono::seconds(1))==std::cv_status::timeout)        
{
    std::cout << '.' << std::endl;
  }
  std::cout << "You entered: " << value << '\n';

  th.join();

  return 0;
}

代码B

#include <sys/time.h>
#include <unistd.h> 
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <chrono>             // std::chrono::seconds
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status

const size_t NUMTHREADS = 1;

pthread_mutex_t mutex;
pthread_cond_t cond;

int value;
bool done = false;

void* read_value( void* id )
{
    const int myid = (long)id; // force the pointer to be a 64bit integer
    std::cin >> value;
    done = true;
    printf( "[thread %d] done is now %d. Signalling cond.\n", myid, done 
);
    pthread_cond_signal( &cond ); 

}

int main ()
{

    struct timeval  now;

    pthread_mutexattr_t Attr;
    pthread_mutexattr_init(&Attr);
    pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&mutex, &Attr);

    pthread_condattr_t CaAttr;
    pthread_condattr_init(&CaAttr);
    pthread_condattr_setclock(&CaAttr, CLOCK_MONOTONIC);
    pthread_cond_init(&cond, &CaAttr);

    std::cout << "Please, enter an integer:\n";
    pthread_t threads[NUMTHREADS];
    int t = 0;
    pthread_create( &threads[t], NULL, read_value, (void*)(long)t );

    struct timespec ts;

    pthread_mutex_lock( &mutex );
    int rt = 0;

    while( !done )
    {
        clock_gettime(CLOCK_MONOTONIC, &ts);
        ts.tv_sec += 1;

        rt = pthread_cond_timedwait( & cond, & mutex, &ts );
        std::cout << "..." << std::endl;
    }

    pthread_mutex_unlock( & mutex );
    std::cout << "You entered: " << value << '\n';

    return 0;

}

1 个答案:

答案 0 :(得分:0)

std::condition_variable::wait_for的文档说:

  

使用稳定的时钟来测量持续时间。

std::chrono::steady_clock

  

std::chrono::steady_clock类代表单调时钟。随着物理时间向前移动,此时钟的时间点不能减少。

不幸的是,这是gcc Bug 41861 (DR887) - (DR 887)(C++0x) does not use monotonic_clock,它使用system_clock代替steady_clock作为条件变量。


一种解决方案是使用wait_until(一定要阅读Notes部分)功能,该功能允许指定相对于特定时钟的持续时间。例如:

cv.wait_until(lck, std::chrono::steady_clock::now() + std::chrono::seconds(1))