C++11 并发指南之std::mutex详解分享!

上一篇《C++11 并发指南二(std::thread 详解) 》中主要讲到了 std::thread 的一些用法,并给出了两个小例子,本文将介绍 std::mutex 的用法。

Mutex 又称互斥量,C++ 11中与 Mutex 相关的类(包括锁类型)和函数都声明在 <mutex> 头文件中,所以如果你需要使用 std::mutex,就必须包含 <mutex> 头文件。

<mutex> 头文件介绍
Mutex 系列类(四种)

Lock 类(两种)

其他类型

函数

std::mutex 介绍

下面以 std::mutex 为例介绍 C++11 中的互斥量用法。

std::mutex 是C++11 中最基本的互斥量,std::mutex 对象提供了独占所有权的特性——即不支持递归地对 std::mutex 对象上锁,而 std::recursive_lock 则可以递归地对互斥量对象上锁。

std::mutex 的成员函数

下面给出一个与 std::mutex 的小例子(参考)

  #include <iostream>  // std::cout  #include <thread>   // std::thread  #include <mutex>   // std::mutex    volatile int counter(0); // non-atomic counter  std::mutex mtx;   // locks access to counter    void attempt_10k_increases() {   for (int i=0; i<10000; ++i) {    if (mtx.try_lock()) { // only increase if currently not locked:     ++counter;     mtx.unlock();    }   }  }    int main (int argc, const char* argv[]) {   std::thread threads[10];   for (int i=0; i<10; ++i)    threads[i] = std::thread(attempt_10k_increases);     for (auto& th : threads) th.join();   std::cout << counter << " successful increases of the counter.n";     return 0;  }    

std::recursive_mutex 介绍

std::recursive_mutex 与 std::mutex 一样,也是一种可以被上锁的对象,但是和 std::mutex 不同的是,std::recursive_mutex 允许同一个线程对互斥量多次上锁(即递归上锁),来获得对互斥量对象的多层所有权,std::recursive_mutex 释放互斥量时需要调用与该锁层次深度相同次数的 unlock(),可理解为 lock() 次数和 unlock() 次数相同,除此之外,std::recursive_mutex 的特性和 std::mutex 大致相同。

std::time_mutex 介绍

std::time_mutex 比 std::mutex 多了两个成员函数,try_lock_for(),try_lock_until()。

try_lock_for 函数接受一个时间范围,表示在这一段时间范围之内线程如果没有获得锁则被阻塞住(与 std::mutex 的 try_lock() 不同,try_lock 如果被调用时没有获得锁则直接返回 false),如果在此期间其他线程释放了锁,则该线程可以获得对互斥量的锁,如果超时(即在指定时间内还是没有获得锁),则返回 false。

try_lock_until 函数则接受一个时间点作为参数,在指定时间点未到来之前线程如果没有获得锁则被阻塞住,如果在此期间其他线程释放了锁,则该线程可以获得对互斥量的锁,如果超时(即在指定时间内还是没有获得锁),则返回 false。

下面的小例子说明了 std::time_mutex 的用法(参考)。

  #include <iostream>  // std::cout  #include <chrono>   // std::chrono::milliseconds  #include <thread>   // std::thread  #include <mutex>   // std::timed_mutex    std::timed_mutex mtx;    void fireworks() {   // waiting to get a lock: each thread prints "-" every 200ms:   while (!mtx.try_lock_for(std::chrono::milliseconds(200))) {   std::cout << "-";   }   // got a lock! - wait for 1s, then this thread prints "*"   std::this_thread::sleep_for(std::chrono::milliseconds(1000));   std::cout << "*n";   mtx.unlock();  }    int main ()  {   std::thread threads[10];   // spawn 10 threads:   for (int i=0; i<10; ++i)   threads[i] = std::thread(fireworks);     for (auto& th : threads) th.join();     return 0;  }  

std::recursive_timed_mutex 介绍

和 std:recursive_mutex 与 std::mutex 的关系一样,std::recursive_timed_mutex 的特性也可以从 std::timed_mutex 推导出来,感兴趣的同鞋可以自行查阅。 ;-)

std::lock_guard 介绍

与 Mutex RAII 相关,方便线程对互斥量上锁。例子(参考):

  #include <iostream>  // std::cout  #include <thread>   // std::thread  #include <mutex>   // std::mutex, std::lock_guard  #include <stdexcept>  // std::logic_error    std::mutex mtx;    void print_even (int x) {   if (x%2==0) std::cout << x << " is evenn";   else throw (std::logic_error("not even"));  }    void print_thread_id (int id) {   try {    // using a local lock_guard to lock mtx guarantees unlocking on destruction / exception:    std::lock_guard<std::mutex> lck (mtx);    print_even(id);   }   catch (std::logic_error&) {    std::cout << "[exception caught]n";   }  }    int main ()  {   std::thread threads[10];   // spawn 10 threads:   for (int i=0; i<10; ++i)    threads[i] = std::thread(print_thread_id,i+1);     for (auto& th : threads) th.join();     return 0;  }    

std::unique_lock 介绍

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/483691.html

(0)
上一篇 2020年11月10日
下一篇 2020年11月10日

精彩推荐