目录
- 1 概述
 - 2 使用实例
 - 3 接口使用
 - 3.1 construct
 - 3.2 lock
 - 3.3 try_lock
 - 3.4 try_lock_for
 - 3.5 try_lock_until
 - 3.6 unlock
 
1 概述
  定时互斥是一种时间可锁定的对象,它设计用于在代码的关键部分需要独占访问时发出信号,就像常规互斥一样,但还支持定时尝试锁定请求。
   因此,timed_mutex有两个额外的成员:try_lock_for和try_lock_until。
 它保证是一个标准布局类。 标准布局类型是一种具有简单线性数据结构和访问控制的类型,可以很容易地用于与用其他编程语言(如C)编写的代码进行通信.
 其类图如下:
 
2 使用实例
struct TimedFunction
{
    volatile int counter = 0;
    void fireworks(std::timed_mutex & muxtex)
    {
        while(!muxtex.try_lock_for(std::chrono::milliseconds(200)))
            ;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        ++counter;
        muxtex.unlock();
    }
    void waitUtil(std::timed_mutex & muxtex, int seconds)
    {
        std::chrono::time_point<std::chrono::system_clock> timePoint 
            = std::chrono::system_clock::now() + std::chrono::seconds(seconds);
        std::cerr << "\n\nWait util " << seconds << " seconds... \n";
        if(muxtex.try_lock_until(timePoint))
        {
            muxtex.unlock();
            counter = 10;
        }
        else
            counter = 5;
    }
    void sleepFor(std::timed_mutex & muxtex, int seconds)
    {
        muxtex.lock();
        std::cerr << "\n\nSleep " << seconds << " seconds... \n";
        std::this_thread::sleep_for(std::chrono::seconds(seconds));
        muxtex.unlock();
    }
};
void TimedMutexSuite::try_lock_for()
{
    std::timed_mutex muxtex;
    TimedFunction function;
    std::thread threads[10];
    for(int i = 0; i < 10; i++)
        threads[i] = std::thread(&TimedFunction::fireworks, std::ref(function), std::ref(muxtex));
    for(auto &thread : threads)
        thread.join();
    TEST_ASSERT_EQUALS(true, function.counter == 10)
    std::cerr << "function.counter: " << function.counter << std::endl;
}
void TimedMutexSuite::try_lock_until()
{
    std::timed_mutex muxtex;
    TimedFunction function;
    std::thread threads[2];
    threads[0] = std::thread(&TimedFunction::sleepFor, std::ref(function), std::ref(muxtex), 10);
    threads[1] = std::thread(&TimedFunction::waitUtil, std::ref(function), std::ref(muxtex), 5);
    threads[0].join();
    threads[1].join();
    TEST_ASSERT_EQUALS(true, function.counter == 5)
    threads[0] = std::thread(&TimedFunction::sleepFor, std::ref(function), std::ref(muxtex), 5);
    threads[1] = std::thread(&TimedFunction::waitUtil, std::ref(function), std::ref(muxtex), 10);
    threads[0].join();
    threads[1].join();
    TEST_ASSERT_EQUALS(true, function.counter == 10)
}
 
3 接口使用
3.1 construct
void addCount(std::timed_mutex & mutex, int & count)
{
    mutex.lock();
    count++;
    mutex.unlock();
}
void TimedMutexSuite::construct()
{
    std::timed_mutex muxtex;
    int count = 0;
    std::thread threads[10];
    for(int i = 0; i < 10; i++)
        threads[i] = std::thread(addCount, std::ref(muxtex), std::ref(count));
    for(auto &thread : threads)
        thread.join();
    TEST_ASSERT_EQUALS(10, count)   
}
 
3.2 lock
void TimedMutexSuite::lock()
{
    std::timed_mutex muxtex;
    int count = 10;
    std::thread threads[10];
    for(int i = 0; i < 10; i++)
        threads[i] = std::thread(addCount, std::ref(muxtex), std::ref(count));
    for(auto &thread : threads)
        thread.join();
    TEST_ASSERT_EQUALS(20, count)   
}
 
3.3 try_lock
struct TimedFunction
{
    volatile int counter = 0;
    void add_10k_count(std::timed_mutex & muxtex)
    {
        for(int i = 0; i < 10000; i++)
        {
            if(muxtex.try_lock())
            {
                ++counter;
                muxtex.unlock();
            }
        }
    }
};
void TimedMutexSuite::try_lock()
{
    std::timed_mutex muxtex;
    TimedFunction function;
    std::thread threads[10];
    for(int i = 0; i < 10; i++)
        threads[i] = std::thread(&TimedFunction::add_10k_count, std::ref(function), std::ref(muxtex));
    for(auto &thread : threads)
        thread.join();
    TEST_ASSERT_EQUALS(true, function.counter < (10 * 10000))
    std::cerr << "function.counter: " << function.counter << std::endl;
}
 
3.4 try_lock_for
struct TimedFunction
{
    volatile int counter = 0;
    void fireworks(std::timed_mutex & muxtex)
    {
        while(!muxtex.try_lock_for(std::chrono::milliseconds(200)))
            ;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        ++counter;
        muxtex.unlock();
    }
    void waitUtil(std::timed_mutex & muxtex, int seconds)
    {
        std::chrono::time_point<std::chrono::system_clock> timePoint 
            = std::chrono::system_clock::now() + std::chrono::seconds(seconds);
        std::cerr << "\n\nWait util " << seconds << " seconds... \n";
        if(muxtex.try_lock_until(timePoint))
        {
            muxtex.unlock();
            counter = 10;
        }
        else
            counter = 5;
    }
    void sleepFor(std::timed_mutex & muxtex, int seconds)
    {
        muxtex.lock();
        std::cerr << "\n\nSleep " << seconds << " seconds... \n";
        std::this_thread::sleep_for(std::chrono::seconds(seconds));
        muxtex.unlock();
    }
};
void TimedMutexSuite::try_lock_for()
{
    std::timed_mutex muxtex;
    TimedFunction function;
    std::thread threads[10];
    for(int i = 0; i < 10; i++)
        threads[i] = std::thread(&TimedFunction::fireworks, std::ref(function), std::ref(muxtex));
    for(auto &thread : threads)
        thread.join();
    TEST_ASSERT_EQUALS(true, function.counter == 10)
    std::cerr << "function.counter: " << function.counter << std::endl;
}
 
说明:
- try_lock_for 如果等待指定时间没有锁定返回false,否则返回true
 
3.5 try_lock_until
void TimedMutexSuite::try_lock_until()
{
    std::timed_mutex muxtex;
    TimedFunction function;
    std::thread threads[2];
    threads[0] = std::thread(&TimedFunction::sleepFor, std::ref(function), std::ref(muxtex), 10);
    threads[1] = std::thread(&TimedFunction::waitUtil, std::ref(function), std::ref(muxtex), 5);
    threads[0].join();
    threads[1].join();
    TEST_ASSERT_EQUALS(true, function.counter == 5)
    threads[0] = std::thread(&TimedFunction::sleepFor, std::ref(function), std::ref(muxtex), 5);
    threads[1] = std::thread(&TimedFunction::waitUtil, std::ref(function), std::ref(muxtex), 10);
    threads[0].join();
    threads[1].join();
    TEST_ASSERT_EQUALS(true, function.counter == 10)
}
 
说明:
- try_lock_until 如果等到指定时间没有锁定返回false,否则返回true
 
3.6 unlock
void TimedMutexSuite::unlock()
{
    std::timed_mutex muxtex;
    int count = 20;
    std::thread threads[10];
    for(int i = 0; i < 10; i++)
        threads[i] = std::thread(addCount, std::ref(muxtex), std::ref(count));
    for(auto &thread : threads)
        thread.join();
    TEST_ASSERT_EQUALS(30, count)   
}
                


















