多个线程同时访问共享资源时,经常会出现冲突等。为了避免这种情况的发生,可以使用互斥量,当一个线程锁住了互斥量后,其他线程必须等待这个互斥量解锁后才能访问它。

thread提供了四种不同的互斥量:

1、独占式互斥量non-recursive (std::mutex)

  独占式互斥量加解锁是成对的,同一个线程内独占式互斥量在没有解锁的情况下,再次对它进行加锁这是不对的,会得到一个未定义行为。

2、递归式互斥量recursive (std::recursive_mutex)

  与独占式互斥量不同的是,同一个线程内在互斥量没有解锁的情况下可以再次进行加锁,不过他们的加解锁次数需要一致,递归式互斥量我们平时可能用得比较少些。

3、允许超时的独占式互斥量non-recursive that allows timeouts on the lock functions(std::timed_mutex)

     用法同独占式互斥量,如果线程1对共享资源的访问时间比较长,这时线程2可能等不了那么久,所以设置一个超时时间,在到了超时时间时如果线程1中的互斥量还没有解锁,线程2就不等了,继续往下执行。

4、允许超时的递归式互斥量recursive mutex that allows timeouts on the lock functions (std::recursive_timed_mutex)

 

下面以外卖为例演示下互斥量和线程锁的用法:假如有50份蛋炒饭,两个下单窗口同时运作,蛋炒饭卖完为止。


代码实操:

头文件:

#ifndef __TestMutex_SCENE_H__
#define __TestMutex_SCENE_H__ #include "cocos2d.h" USING_NS_CC; class TestMutex : public cocos2d::Layer
{
int total;//总量
int selled;//卖出量
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(TestMutex); void threadA();
void threadB();
}; #endif // __TestMutex_SCENE_H__

源文件:

#include "TestMutex.h"
#include <thread> std::mutex _mutex;
Scene* TestMutex::createScene()
{
auto scene = Scene::create();
auto layer = TestMutex::create();
scene->addChild(layer);
return scene;
} bool TestMutex::init()
{
if ( !Layer::init() )
{
return false;
} total = 50;
selled = 0; std::thread t1(&TestMutex::threadA,this);
t1.detach(); std::thread t2(&TestMutex::threadB,this);
t2.detach(); return true;
}
void TestMutex::threadA()
{
while (selled<total)
{
// 加锁
_mutex.lock();
selled++;
std::this_thread::sleep_for(std::chrono::seconds(3));
log("threadA %d",selled);
// 解锁
_mutex.unlock();
}
} void TestMutex::threadB()
{
while (selled<total)
{
_mutex.lock();
selled++;
std::this_thread::sleep_for(std::chrono::seconds(3)); log("threadB %d",selled);
_mutex.unlock();
}
}

Cocos2d-X多线程(2) 线程的互斥量std::mutex和线程锁的更多相关文章

  1. pThreads线程(二) 线程同步--互斥量/锁

    互斥量(Mutex)是“mutual exclusion”的缩写.互斥量是实现线程同步,和保护同时写共享数据的主要方法. 互斥量对共享数据的保护就像一把锁.在Pthreads中,任何时候仅有一个线程可 ...

  2. c++11 线程的互斥量

    c++11 线程的互斥量 为什么需要互斥量 在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源.这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在 ...

  3. 多线程面试题系列(7):经典线程同步 互斥量Mutex

    前面介绍了关键段CS.事件Event在经典线程同步问题中的使用.本篇介绍用互斥量Mutex来解决这个问题. 互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问.互斥量与关键段的行为非常相似, ...

  4. 秒杀多线程第七篇 经典线程同步 互斥量Mutex

    本文转载于:http://blog.csdn.net/morewindows/article/details/7470936 前面介绍了关键段CS.事件Event在经典线程同步问题中的使用.本篇介绍用 ...

  5. 转--- 秒杀多线程第七篇 经典线程同步 互斥量Mutex

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  6. 经典线程同步 互斥量Mutex

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  7. (转)经典线程同步 互斥量Mutex

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  8. windows多线程(五) 互斥量 Mutex

    一.互斥量 互斥量是windows的一个内核对象,互斥量与关键段的作用相似,可以用来确保全局资源的互斥访问.并且互斥量可以用在不同的进程中的线程互斥访问全局资源. 二.相关函数说明 使用互斥量Mute ...

  9. 生产者-消费者问题:介绍POSIX线程的互斥量和条件变量的使用

    全局初始化互斥量和条件变量(不全局也行,但至少要对线程启动函数可见,这样才能使用.) static pthread_cont_t cond = PTHREAD_COND_INITIALIZER; st ...

随机推荐

  1. k8spod生命周期

    pod对象自从创建开始至终止退出的时间范围称为生命周期,在这段时间中,pod会处于多种不同的状态,并执行一些操作:其中,创建主容器为必须的操作,其他可选的操作还包括运行初始化容器(init conta ...

  2. linux学习:【第2篇】之常见命令

    linux之常见命令 创建一个目录 /data mkdir /data ls -l /data/ cd /data/ pwd 相对路径与绝对路径 1.绝对路径 从根开始的路径 /data 2.相对路径 ...

  3. cordova打包项目下载gradle失败

    在使用cordova打包项目的时候有时会因为网络环境原因导致下载gradle失败的情况,个人找到两种解决方案. 方案一: 根据报错的提示选择要下载的gradle去浏览器中下载,然后将gradle压缩包 ...

  4. ASP.NET上传断点续传

    IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag 客户端每次提交下载请求时,服务 ...

  5. codevs 1405 牛的旅行x

    牛的旅行 [问题描述] 农民John的农场里有很多牧区.有的路径连接一些特定的牧区.一片所有连通的牧区称为一个牧场.但是就目前而言,你能看到至少有两个牧场不连通.现在,John想在农场里添加一条路径 ...

  6. MySQL数据库入门———常用基础命令

    mysql 连接数据库命令: MySQL 连接本地数据库,用户名为“root”,密码“123”(注意:“-p”和“123” 之间不能有空格) mysql -h localhost -u root -p ...

  7. js模拟24小时的倒计时效果

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. python学习之路(3)

    字符串和编码 因为python最早只支持ASCII编码普通的字符串'ABC'在Python内部都是ASCII编码的.Python提供了ord()和chr()函数,可以把字母和对应的数字相互转换 后来p ...

  9. Java Optional orElse() 和 orElseGet() Optional.flatMap()和Optional.map()区别

    Java Optional 的 orElse() 和 orElseGet() 的区别 1. 接收的参数不同 orElse()方法以一个自定义类型的数据作为参数 public T orElse(T t) ...

  10. 从零开始学习vue(2)

    一.vue实例 每个vue应用都是通过Vue构造函数创建的一个新的实例开始的: var vm = new Vue({ //选项对象 }) 在这其中vm(viewModel的简称)通常都表示vue实例的 ...