互斥锁是用来保护一段临界区的,它可以保证某段时间内只有一个线程在执行一段代码或者访问某个资源。

C++11的mutex和lock_guard

C++11新增了mutex,使用方法和linux底下的常用使用方法差不多。先使用std::mutex 定义一个互斥锁,例如std::mutex XXXmutex在需要使用互斥锁的时候,使用XXXmutex.lock();上锁,以及使用XXXmutex.unlock();解锁。下面是一段参考代码:

#include <iostream>
#include <map>
#include <string>
#include <chrono>
#include <thread>
#include <mutex> std::map<std::string, std::string> g_pages;
std::mutex g_pages_mutex; void save_page(const std::string &url)
{
// simulate a long page fetch
std::this_thread::sleep_for(std::chrono::seconds(2));
std::string result = "fake content"; g_pages_mutex.lock();
g_pages[url] = result;
g_pages_mutex.unlock();
} int main()
{
std::thread t1(save_page, "http://foo");
std::thread t2(save_page, "http://bar");
t1.join();
t2.join(); g_pages_mutex.lock(); // not necessary as the threads are joined, but good style
for (const auto &pair : g_pages) {
std::cout << pair.first << " => " << pair.second << '\n';
}
g_pages_mutex.unlock();
}
t2.join();
}

使用mutex的时候需要手动上锁还有解锁,C++11提供了另一个利器–>lock_guard,它是与mutex配合使用,把锁放到lock_guard中时,mutex自动上锁,lock_guard析构时,同时把mutex解锁。使用的应该就是所谓的RAII技法(RAII,,也称为“资源获取就是初始化”,是C++语言的一种管理资源、避免泄漏的惯用法。C++标准保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。简单的说,RAII 的做法是使用一个对象,在其构造时获取资源,在对象生命期控制对资源的访问使之始终保持有效,最后在对象析构的时候释放资源。)

下面是另一段示例代码:

#include <thread>
#include <mutex> int g_i = 0;
std::mutex g_i_mutex; // protects g_i void safe_increment()
{
std::lock_guard<std::mutex> lock(g_i_mutex);
++g_i; // g_i_mutex is automatically released when lock
// goes out of scope
} int main()
{
std::thread t1(safe_increment);
std::thread t2(safe_increment); t1.join();
t2.join();
}

使用lock_guard的时候不需要手动解锁,资源获取即初始化,析构的时候就会自动解锁,使用起来会相对比较方便。

muduo的MutexLock 与MutexLockGuard

muduo库里面也封装了两个类似的类:MutexLock 与MutexLockGuard。

MutexLock 封装临界区(critical section),这是一个简单的资源类,用RAII 手法[CCS,条款13] 封装互斥器的创建与销毁。临界区在Windows 上是struct CRITICAL_SECTION,是可重入的;在Linux 下是pthread_mutex_t,默认是不可重入的。MutexLock 一般是别的class 的数据成员。

MutexLockGuard 封装临界区的进入和退出,即加锁和解锁。MutexLockGuard 一般是个栈上对象,它的作用域刚好等于临界区域。

MutexLockGuard类使用RAII技法封装,在实际应用中这个类更常用,作为class 数据成员的MutexLock 只能用于同步本class 的其他数据成员的读和写,它不能保护安全地析构。因为MutexLock 成员的生命期最多与对象一样长,而析构动作可说是发生在对象身故之后(或者身亡之时)。

使用方法:muduo的MutexLock 与MutexLockGuard使用方法也是很简单的,MutexLockGuard负责加锁解锁,MutexLock 封装临界区,所以MutexLockGuard需要和MutexLock 配合使用,一般应先使用MutexLock定义一个临界区,然后将该MutexLock作为参数传进MutexLockGuard对象,例如:

MutexLock mutex_;//互斥锁
MutexLockGuard lock(mutex_);

这样在MutexLockGuard对象生命期结束的时候会自动解锁。那么他的生命期什么时候结束呢?一般如果只是上锁一小段代码,而该代码后面还有很多的语句,那么可以使用大括号将想要锁定的区域括起来。

C++11的mutex和lock_guard,muduo的MutexLock 与MutexLockGuard的更多相关文章

  1. 基于std::mutex std::lock_guard std::condition_variable 和std::async实现的简单同步队列

    C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为.通常的做法是在修改共享数据成员的时候进行加锁--mutex.在使用锁的时候通 ...

  2. 39.mutex 的lock_guard与unique_lock

    #include <iostream> #include <thread> #include <mutex> using namespace std; #defin ...

  3. C++ 11 多线程下std::unique_lock与std::lock_guard的区别和用法

    这里主要介绍std::unique_lock与std::lock_guard的区别用法 先说简单的 一.std::lock_guard的用法 std::lock_guard其实就是简单的RAII封装, ...

  4. C++11 并发指南三(std::mutex 详解)

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

  5. C++11并发——多线程std::mutex (二)

    https://www.cnblogs.com/haippy/p/3237213.html Mutex 又称互斥量,C++ 11中与 Mutex 相关的类(包括锁类型)和函数都声明在 <mute ...

  6. C++11中的mutex, lock,condition variable实现分析

    本文分析的是llvm libc++的实现:http://libcxx.llvm.org/ C++11中的各种mutex, lock对象,实际上都是对posix的mutex,condition的封装.不 ...

  7. C++11 并发指南三(std::mutex 详解)(转)

    转自:http://www.cnblogs.com/haippy/p/3237213.html 上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::th ...

  8. 【C/C++开发】C++11 并发指南三(std::mutex 详解)

    本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C ...

  9. C++11 并发指南三(Lock 详解)

    在 <C++11 并发指南三(std::mutex 详解)>一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型.本节将详细介绍一下 C++11 标准 ...

随机推荐

  1. matplotlib Bbox类

    Bbox 类是一个可变的(相对于BboxBase)限位框, 继承自BboxBase 2020-04-07 22:54:57  --Edit by yangray 方法: __init__(points ...

  2. Redis对象——有序集合(ZSet)

    有序集合类型 (Sorted Set或ZSet) 相比于集合类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序结合的元素值,一个是排序 ...

  3. 【小学数学】算术口诀 独立音频MP3

    算术口诀 独立音频MP3 原文载于本人个人网站:http://www.unlimitedbladeworks.cc/writing_202004_01_sskj 特点 加法口诀 乘法口诀 独立音频 m ...

  4. AJ学IOS(33)UI之Quartz2D雪花飘落效果刷帧

    AJ分享,必须精品 效果: 可以加入随机数实现真的飘落效果哦. 代码: -(id)initWithCoder:(NSCoder *)aDecoder { //请注意这里一定要先初始化父类的构造方法 i ...

  5. day02,静态库和动态库

    一.首先我们来看一下什么是静态库和动态库,在这之前我们来看一下编译成可执行文件的过程: 1.静态库(.a..lib):就是在使用的时候会把代码复制到文件中: 它的优点:独立,在链接后不需要静态库源文件 ...

  6. 安全测试-WEB安全渗透测试基础知识(四)

    .4. HTTP标准 1.4.1. 报文格式 1.4.1.1. 请求报文格式 <method><request-URL><version> <headers& ...

  7. Windows Pains poj 2585

    Boudreaux likes to multitask, especially when it comes to using his computer. Never satisfied with j ...

  8. 如何在Ubuntu 18.04上安装Nginx

    Nginx功能之强大,想必大家比我更清楚. 百度百科:Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务.Nginx是由伊戈尔 ...

  9. 基于MySQL Binlog的Elasticsearch数据同步实践

    一.为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品.订单等数据的多维度检索. 使用 Elasticsearch 存储业务数 ...

  10. Spring Boot 自定义kafka 消费者配置 ContainerFactory最佳实践

    Spring Boot 自定义kafka 消费者配置 ContainerFactory最佳实践 本篇博文主要提供一个在 SpringBoot 中自定义 kafka配置的实践,想象这样一个场景:你的系统 ...