boost Mutex

写过多线程程序的人都知道,不能让多个线程同时访问共享的资源是至关重要的。

假如一个线程试图改变共享数据的值,而另外一个线程试图去读取该共享数据的值,结果将是未定义的。

为了阻止这样的事情发生,需要用到一些非凡的原始数据类型和操作。其中最重的一个就是总所周知的mutex(“mutual exclusion的缩写。译注:相互排斥的意思,经常被翻译为互斥体”)

mutex在同一时间只能答应一个线程访问共享资源。当一个线程需要访问共享资源时,它必须先锁住”mutex,假如任何其他线程已经锁住了mutex,那么本操作将会一直被阻塞,直到锁住了mutex的线程解锁,这就保证了共享资源,在同一时间,只有一个线程可以访问。

mutex的概念有几个变种。Boost.Threads支持两大类型的mutex简单mutex和递归mutex。一个简单的mutex只能被锁住一次,假如同一线程试图两次锁定mutex,将会产生死锁。对于递归mutex,一个线程可以多次锁定一个mutex,但必须以同样的次数对mutex进行解锁,否则其他线程将无法锁定该mutex

在上述两大类mutex的基础上,一个线程如何锁定一个mutex也有些不同变化。一个线程有3种可能方法来锁定mutex

1. 等待并试图对mutex加锁,直到没有其他线程锁定mutex

2. 试图对mutex加锁,并立即返回,假如其他线程锁定了mutex

3. 等待并试图对mutex加锁,直到没有其他线程锁定mutex或者直到规定的时间已过。


看起来最好的mutex类型是递归的mutex了,因为上述3种加锁的方式它都支持。不过,不同的加锁方式有不同的消耗,因此对于特定的应用,Boost.Threads答应你挑选最有效率的mutex

为此,Boost.Threads提供了6中类型的mutex,效率由排列:

boost::mutex

boost::try_mutex

boost::timed_mutex

boost::recursive_mutex

boost::recursive_try_mutex

boost::recursive_timed_mutex

假如一个线程锁定一个mutex后,而没有解锁,就会发生死锁,这也是最为常见的错误了,为此,Boost.Threads专门进行了设计,可不直接对mutex加锁或者解锁操作,以使这种错误不可能发生(或至少很难发生)

取而代之地,mutex类定义了内嵌的typedef来实现RAII(Resource Acquisition In Initialization,译注:在初始化时资源获得)[4]用以对一个mutex进行加锁或者解锁,这就是所谓的Scoped Lock模式。要构建一个这种类型的锁,需要传送一个mutex引用,构造函数将锁定mutex,析构函数将解锁mutexC++语言规范确保了析构函数总是会被调用,所以即使有异常抛出,mutex也会被正确地解锁。

这种模式确保了mutex的正确使用。不过必须清楚,尽管Scoped Lock模式保证了mutex被正确解锁,但它不能保证在有异常抛出的时候,所有共享资源任然处于有效的状态,所以,就像进行单线程编程一样,必须确保异常不会让程序处于不一致的状态。同时,锁对象不能传送给另外一个线程,因为他们所维护的状态不会受到此种用法的保护。


列表2举例说明了boost::mutex类的一个简单的用法。其中两个线程被创建,每个循环10次,将id和当前循环计数输出到std::coutmain线程等待着两个线程结束。std::cout对象是一个共享资源,所以每个线程均使用全局mutex,以确保在同一时刻,只有一个线程输出到它。

#include <boost/thread/thread.hpp>

#include <boost/thread/mutex.hpp>

#include <iostream>

boost::mutex io_mutex;

struct count

{

    count(int id) : id(id) { }

    void operator()()

    {

         for (int i = 0; i < 10; ++i)

        {

            boost::mutex::scoped_lock lock(io_mutex);

            std::cout << id << ": " << i << std::endl;

        }

    }

    int id;

};

int main(int argc, char* argv[])

{

    boost::thread thrd1(count(1));

    boost::thread thrd2(count(2));

    thrd1.join(); //函数来等待线程结束

    thrd2.join();

    return 0;

}

列表2

也许你已经注重到在列表2的代码中,需要手工写一个函数对象,才能向线程传送数据。尽管代码很简单,但每次都要写这样的代码也会让人有单调沉闷之感。有另外一种更轻易的解决办法,Functional库可以让你通过将需要传入的数据绑定到另外一个函数对象的方式,来创建一个新的函数对象。列表3展现了Boost.Bind库如何不写函数对象,而简化列表2中的代码。

// This program is identical to listing2.cpp except that it uses

// Boost.Bind to simplify the creation of a thread that takes data.

#include <boost/thread/thread.hpp>

#include <boost/thread/mutex.hpp>

#include <boost/bind.hpp>

#include <iostream>

boost::mutex io_mutex;

void count(int id)

{

for (int i = 0; i < 10; ++i)

{

boost::mutex::scoped_lock lock(io_mutex);

std::cout << id << ": " << i << std::endl;

}

}

int main(int argc, char* argv[])

{

boost::thread thrd1(boost::bind(&count, 1)); // 有无&符号均可

boost::thread thrd2(boost::bind(&count, 2)); // 有无&符号均可

thrd1.join();

thrd2.join();

return 0;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

接入支付宝出现交易订单处理失败,请稍后再试(ALI64)的错误

上次在接入支付宝的时候就碰到了交易订单处理失败&#xff0c;请稍后再试&#xff08;ALI64&#xff09;这样的错误&#xff0c;后来经过排查和总结&#xff0c;一般来讲这种问题都是公钥和私钥没有正确配置造成的。支付宝这边为了保证数据在传输时不被篡改&#xff0c;使用了r…

c中session的用法

c中session的用法你知道吗&#xff1f;下面小编就跟你们详细介绍下c中session的用法&#xff0c;希望对你们有用。c中session的用法如下&#xff1a;Session的基本属性&#xff1a;一、属性1、SessionIDSessionID 属性返回用户的会话标识。在创建会话时&#xff0c;服务器会为每…

查看硬件信息

测试机器的硬件信息&#xff1a; 查看CPU信息&#xff08;型号&#xff09; # cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c 8 Intel(R) Xeon(R) CPU E5410 2.33GHz (看到有8个逻辑CPU, 也知道了CPU型号) # cat /proc/cpuinfo | grep physical …

支付宝集成交互流程

交互流程 功能流程 流程说明&#xff08;以Android平台为例&#xff09;&#xff1a; 第4步&#xff1a;调用支付接口&#xff1a;此消息就是本接口所描述的开发包提供的支付对象PayTask&#xff0c;将商户签名后的订单信息传进pay方法唤起支付宝收银台&#xff0c;订单格式具体…

VxLAN基础

转自&#xff1a;http://blog.csdn.net/freezgw1985/article/details/16354897 一 . 为什么需要Vxlan1. vlan的数量限制4096个vlan远不能满足大规模云计算数据中心的需求2. 物理网络基础设施的限制基于IP子网的区域划分限制了需要二层网络连通性的应用负载的部署3. TOR交换机MA…

find_first_of()和 find_last_of() 【获取路径、文件名】

string 类提供字符串处理函数&#xff0c;利用这些函数&#xff0c;程序员可以在字符串内查找字符&#xff0c;提取连续字符序列(称为子串)&#xff0c;以及在字符串中删除和添加。我们将介绍一些主要函数。 1.函数find_first_of()和 find_last_of() 执行简单的模式匹配&#x…

支付宝集成

memo Error Domain系统繁忙&#xff0c;请稍后再试 Code1000 "(null)" reslut {memo "Error Domain\U7cfb\U7edf\U7e41\U5fd9\Uff0c\U8bf7\U7a0d\U540e\U518d\U8bd5 Code1000 \"(null)\"";result "";resultStatus 4000;} 请问安装…

servlet中实现页面跳转return “r:”和return “f:

servlet中实现页面跳转return “r&#xff1a;”和return “f&#xff1a;”的区别和作用 分享| 2015-07-28 14:22741830480 | 浏览 48 次Pascal2015-07-28 14:26 #知道行家专业创造价值&#xff0c;火热招募中&#xff01;#提问者采纳热心网友r是redirect重定向&#xff0c;参…

多线程编程 RW_LOCK 读写锁

RW锁 读写锁&#xff0c;也叫共享独占锁 互斥量 要么是锁住状态&#xff0c;要么是不加锁状态&#xff0c;而且一次只有一个线程可以对其加锁。 读写锁可以有三种状态&#xff0c;读模式下加锁状态&#xff0c;写模式下加锁状态&#xff0c;不加锁状态。一次只有一个线程可以占…

Error Domain=NSCocoaErrorDomain Code=3840 JSON text did not start with array or object and option

数据请求失败 报错 Error DomainNSCocoaErrorDomain Code3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo{NSDebugDescriptionJSON text did not start with array or object and option to allow fragm…

vim学习笔记(4)帮助与配置

使用帮助 在Vim中输入命令&#xff1a;help&#xff0c;即可进入帮助界面&#xff0c;默认是英文&#xff0c;可以通过以下方式安装中文帮助&#xff08;以vimcdoc-1.9.0为例&#xff09;&#xff1a; 1、下载中文帮助的文件压缩包 2、解压 tar -xzvf vimcdoc-1.9.0.tar.gz 3、…

C语言程序代码优化

我认为一个好的用于科学计算的程序代码应该&#xff1a;算法漂亮精妙&#xff0c;程序简洁易懂&#xff0c;运算快速&#xff0c;节省内存。这里有的地方是矛盾的&#xff0c;比如简洁vs易懂&#xff0c;时间vs空间&#xff0c;找个平衡吧。目前来看时间要比空间宝贵一些。写程…

微信支付不回调支付成功的方法,这是为什么

如果你是Xcode7.2&#xff0c;或者IOS9.2的话&#xff0c;可能会遇见在微信客户端操作返回程序之后不能执行微信的onResp回调方法的问题&#xff0c;就是因为一下这两个方法被废弃掉了&#xff0c;所以我的新demo替换了一个新的方法在下面。就完美解决这个问题了&#xff08;并…

如何在苹果官网下载旧版本的Xcode 方法

1 在百度里输入“苹果开发者中心“&#xff0c;进入以下页面。点击页面中的“Member Center" 2 出现登录界面。这是需要苹果开发者帐号的&#xff0c;没有帐号的可以选择“Create Apple ID”进行注册。已经注册的选择“Sign In"登录 3 页面跳转后&#xff0c;选择…

屏幕尺寸 分辨率

1、分辨率 分辨率又称显示分辨率、屏幕分辨率 确定手机屏幕上显示多少信息的设置&#xff0c;以水平和垂直像素来衡量 6 750 *1334 像素 5s 640 * 1136 像素 2、屏幕尺寸 屏幕大小的物理尺寸&#xff0c;以屏幕对角线长度衡量 单位&#xff1a;英寸 1英寸2.54厘米 6 4.7英…

程序代码优化2

程序进行优化&#xff0c;通常是指优化程序代码或程序执行速度。优化代码和优化速度实际上是一个予盾的统一&#xff0c;一般是优化了代码的尺寸&#xff0c;就会带来执行时间的增加&#xff0c;如果优化了程序的执行速度&#xff0c;通常会带来代码增加的副作用&#xff0c;很…

【转】android多分辨率适配

前一阶段开发android项目&#xff0c;由于客户要求进行多分辨率适配&#xff0c;能够支持国内主流的分辨率手机。因此经过了几次开发走了很多弯路&#xff0c;目前刚刚领略了android多分辨率适配的一些方法。 先介绍一下所走的弯路&#xff0c;由于android的布局文件存放在res的…

TCP/IP SOCKET HTTP及HTTPS之间的关系

GET跟POST的区别&#xff1a; get只能传送128K的数据 而post是无限制的 post提交是不在会IE上带上参数 就算你加密了别人也会解密 一般比较重要的数据通过post 传&#xff0c;因为get是别人可以改参数值的 别人乱写参数&#xff0c;你的异常报个不停 网络七层由下往上分别为物理…

静态链接与动态链接的区别

动态链接库、静态库、import库区别 动态链接库(Dynamic Linked Library)&#xff1a; Windows为应用程序提供了丰富的函数调用&#xff0c;这些函数调用都包含在动态链接库中。其中有3个最重要的DLL&#xff0c;Kernel32.dll&#xff0c;它包含用于管理内存、进程和线程的各个函…

Java线程池介绍

根据摩尔定律&#xff08;Moore’s law&#xff09;&#xff0c;集成电路晶体管的数量差不多每两年就会翻一倍。但是晶体管数量指数级的增长不一定会导致 CPU 性能的指数级增长。处理器制造商花了很多年来提高时钟频率和指令并行。在新一代的处理器上&#xff0c;单线程程序的执…