boost库中thread多线程详解2——mutex与lock

1. mutex对象类

mutex类主要有两种:独占式与共享式的互斥量。
▲ 独占式互斥量:
mutex: 独占式的互斥量,是最简单最常用的一种互斥量类型
try_mutex: 它是mutex的同义词,为了与兼容以前的版本而提供
timed_mutex: 它也是独占式的互斥量,但提供超时锁定功能
▲ 递归式互斥量:
recursive_mutex: 递归式互斥量,可以多次锁定,相应地也要多次解锁
recursive_try_mutex: 它是recursive_mutex 的同义词,为了与兼容以前的版本而提供
recursive_timed_mutex: 它也是递归式互斥量,基本功能同recursive_mutex, 但提供超时锁定功能
▲ 共享式互斥量:
shared_mutex: multiple-reader/single-writer 型的共享互斥量(又称读写锁)。
其中mutex有lock和unlock方法,shared_mutex除了提供lock和unlock方法外,还有shared_lock和shared_unlock方法。

2. lock模板类

▲ 独占锁:
boost::unique_lock<T>,其中T可以mutex中的任意一种。
  如果T为mutex,那么boost::unique_lock<boost::mutex>,构造与析构时则分别自动调用lock和unlock方法。
  如果T为shared_mutex,那么boost::unique_lock<boost::shared_mutex>,构造与析构时则分别调用shared_mutex的shared_lock和shared_unlock方法。
注意:scoped_lock也是独占锁,其源代码中定义如下;
  typedef unique_lock<mutex> scoped_lock;
  typedef unique_lock<timed_mutex> scoped_timed_lock;
▲ 共享锁:
boost::shared_lock<T>,其中的T只能是shared_mutex类。
当然还有其他一些锁:lock_guard, upgrade_lock等。

3. 读写锁的实现

[cpp] view plaincopyprint?

  1. typedef boost::shared_lock<boost::shared_mutex> readLock;
  2. typedef boost::unique_lock<boost::shared_mutex> writeLock;
  3. boost::shared_mutex rwmutex;
  4. void readOnly()
  5. {
  6. readLock rdlock(rwmutex);
  7. // do something
  8. }
  9. void writeOnly()
  10. {
  11. writeLock wtlock(rwmutex);
  12. // do something
  13. }

对同一个rwmutex,线程可以同时有多个readLock,这些readLock会阻塞任意一个企图获得writeLock的线程,直到所有的readLock对象都析构。如果writeLock首先获得了rwmutex,那么它会阻塞任意一个企图在rwmutex上获得readLock或者writeLock的线程。

4. boost::lock_guard<>和boost::unique_lock<>的区别

[cpp] view plaincopyprint?

  1. boost::mutex m;
  2. void foo( )
  3. {
  4. boost::lock_guard<boost::mutex> lk(m);
  5. process(data);
  6. };
  7. // lock_guard只能像上面这样使用,而unique_lock允许设置超时,推迟锁定lock以及在对象销毁之前unlock。
  8. {
  9. boost::unique_lock<boost::mutex> lk( m );
  10. process( data );
  11. lk.unlock( );
  12. // do other thing
  13. };
  14. // 设置锁超时
  15. {
  16. boost::unique_lock<boost::timed_mutex> lk(m, std::chrono::milliseconds(3)); // 超时3秒
  17. if(lk)
  18. process( data );
  19. };

5. 简单示例

[cpp] view plaincopyprint?

    1. namespace
    2. {
    3. boost::mutex mutex;
    4. boost::shared_mutex shared_mutex;
    5. void wait(int seconds)
    6. {
    7. boost::this_thread::sleep(boost::posix_time::seconds(seconds));
    8. }
    9. void threadfun1()
    10. {
    11. for (int i = 0; i < 5; ++i)
    12. {
    13. wait(1);
    14. mutex.lock();
    15. PRINT_DEBUG(i);
    16. mutex.unlock();
    17. }
    18. }
    19. void threadfun2()
    20. {
    21. for (int i = 0; i < 5; ++i)
    22. {
    23. wait(1);
    24. boost::lock_guard<boost::mutex> lock(mutex);
    25. PRINT_DEBUG(i);
    26. }
    27. }
    28. void threadfun3()
    29. {
    30. for (int i = 0; i < 5; ++i)
    31. {
    32. wait(1);
    33. // unique_lock<boost::mutex> = scoped_lock
    34. boost::unique_lock<boost::mutex> lock(mutex);
    35. std::cout << lock.owns_lock() << std::endl;
    36. PRINT_DEBUG(i);
    37. }
    38. }
    39. }
    40. // 1. mutex例子
    41. void test_thread_syn1()
    42. {
    43. boost::thread t1(&threadfun1);
    44. boost::thread t2(&threadfun1);
    45. t1.join();
    46. t2.join();
    47. }
    48. //  2. lock_guard例子
    49. void test_thread_syn2()
    50. {
    51. boost::thread t1(&threadfun2);
    52. boost::thread t2(&threadfun2);
    53. t1.join();
    54. t2.join();
    55. }
    56. // 3. scoped_lock例子
    57. void test_thread_syn3()
    58. {
    59. boost::thread t1(&threadfun3);
    60. boost::thread t2(&threadfun3);
    61. t1.join();
    62. t2.join();
    63. }
时间: 2024-12-13 13:26:32

boost库中thread多线程详解2——mutex与lock的相关文章

seaborn库中柱状图绘制详解

柱状图用于反映数值变量的集中趋势,用误差线估计变量的差值统计.理解误差线有助于我们准确的获取柱状图反映的信息,因此打算先介绍一下误差线方面的内容,然后介绍一下利用seaborn库绘制柱状图. 1.误差线的理解 误差线源于统计学,表示数据误差(或不确定性)范围,以更准确的方式呈现数据.当label上有一组采样数据时,一般将这组数据的平均值作为该label上标注的值,而用误差线表示该均值可能的误差范围.误差线可以用标准差(standard deviation,SD).标准误(standard err

java多线程详解

转自:线程间通信.等待唤醒机制.生产者消费者问题(Lock,Condition).停止线程和守护线程.线程优先级 1  线程间通信 1.1  线程间通信 其实就是多个线程在操作同一个资源,但是操作的动作不同. 比如一个线程给一个变量赋值,而另一个线程打印这个变量. 1.2  等待唤醒机制 wait():将线程等待,释放了CPU执行权,同时将线程对象存储到线程池中. notify():唤醒线程池中一个等待的线程,若线程池有多个等待的线程,则任意唤醒一个. notifyAll():唤醒线程池中,所有

python中threading模块详解(一)

python中threading模块详解(一) 来源 http://blog.chinaunix.net/uid-27571599-id-3484048.html threading提供了一个比thread模块更高层的API来提供线程的并发性.这些线程并发运行并共享内存. 下面来看threading模块的具体用法: 一.Thread的使用 目标函数可以实例化一个Thread对象,每个Thread对象代表着一个线程,可以通过start()方法,开始运行. 这里对使用多线程并发,和不适用多线程并发做

Java 多线程详解(二)------如何创建进程和线程

Java 多线程详解(一)------概念的引入:http://www.cnblogs.com/ysocean/p/6882988.html 在上一篇博客中,我们已经介绍了并发和并行的区别,以及进程和线程的理解,那么在Java 中如何创建进程和线程呢? 1.在 Windows 操作系统中创建进程 在 windows 操作系统中,我们创建一个进程通常就是打开某个应用软件,这便在电脑中创建了一个进程.更原始一点的,我们在命令提示符中来做(我们以打开记事本这个进程为例): 第一步:windows+R,

Java 多线程详解(五)------线程的声明周期

Java 多线程详解(一)------概念的引入:http://www.cnblogs.com/ysocean/p/6882988.html Java 多线程详解(二)------如何创建进程和线程:http://www.cnblogs.com/ysocean/p/6883491.html Java 多线程详解(三)------线程的同步:http://www.cnblogs.com/ysocean/p/6883729.html Java 多线程详解(四)------生产者和消费者:http:/

oracle dataguard主备库参数文件配置详解

主库参数详解: 保持同一个Data Guard中所有的DB_NAME相同 DB_NAME=ora11g 为一个数据库指定一个唯一的名称,该参数一经指定就不会发生改动除非DBA主动改动 DB_UNIQUE_NAME=ora11g_primary 初始化参数LOG_ARCHIVE_CONFIG用于控制发送归档日志到远程位置.接收远程归档日志,并指定Data  Guard配置的惟一数据库名,默认值为SEND,RECEIVE,NODG_CONFIG. 当设置该参数为SEND时,会激活发送归档日志到远程位

Java 多线程详解(三)------线程的同步

Java 多线程详解(一)------概念的引入:http://www.cnblogs.com/ysocean/p/6882988.html Java 多线程详解(二)------如何创建进程和线程:http://www.cnblogs.com/ysocean/p/6883491.html 介绍完如何创建进程以及线程了,那么我们接着来看一个实例: 利用多线程模拟 3 个窗口卖票 第一种方法:继承 Thread 类 创建窗口类 TicketSell package com.ys.thread; p

Java多线程详解与晋级(一)

Java多线程详解与晋级(一) Java线程的概念与原理 一.操作系统中线程和进程的概念 进程是指操作系统内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程. 线程是指进程中的一个执行流程,一个进程中可以运行多个线程.比如java.exe进程中可以运行很多线程.线程总是属于某个进程,进程中的多个线程共享进程的内存. 简单来说,进程就是一个应用程序在操作系统上的一次执行过程,而线程是进程中的一次执行流程,进程包含多个线程在运行. 二.Java的线程 Thread类

Android研究之游戏开发多线程详解

 游戏开发与软件开发多线程的重要性       如果程序主线程被阻塞超过5秒,系统会提示"应用程序无响应" 这就是ANR . ANR的全称是Application Not Responding,使用多线程可以避免ANR.但是这里要注意一下不要为了避免ANR而过多的使用多线程,除非万不得已的情况. 比如访问网络服务端返回的过慢.数据过多导致滑动屏幕不流畅.或者I/O读取过大的资源等等.这里可以开启一个新线程来处理这些耗时的操作. 如果过多使用多线程会出现数据同步的问题须要程序员去处理