本篇接上篇继续讲:上篇传送门http://blog.csdn.net/star530/article/details/24186783

简单的东西我都说的几乎相同了,想挖点深的差点把自己给填进去。

以下实际演练一下。请同意我參考偶尔E往事的一篇线程的博客, 他用的是pThread。这里我就用std::thread。

1.售票
孙鑫老师的C++和Java多线程售票也一直让我念念不忘(好吧,我承认我没看过)。这里用cocos2d-x3.0和C++11的std::thread实现一个吧。总共同拥有100张诺亚方舟船票。有2个售票点A和B在售票(一张票就一百亿美元吧)。当票卖完了就结束了。我们知道当程序一開始进程就会创建一个主线程,所以能够在主线程基础上再创建2个线程A和B,再线程A和B中分别售票,当票数为0的时候,结束线程A和B。

2.多线程售票,代码例如以下:

//HelloWorld.h
class HelloWorld : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init(); CREATE_FUNC(HelloWorld); void myThreadA();//线程A
void myThreadB();//线程B int tickets;//票数 }; //.cpp
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
} tickets = 100;//100张票 std::thread tA(&HelloWorld::myThreadA,this);//创建一个分支线程,回调到myThread函数里
std::thread tB(&HelloWorld::myThreadB,this);
tA.detach();
tB.detach();
// t1.detach(); CCLOG("in major thread");//在主线程
return true;
} void HelloWorld::myThreadA()
{
while(true)
{
if(tickets>0)
{
Sleep(10);
CCLOG("A Sell %d",tickets--);//输出售票。每次减1
}
else {
break;
}
}
}
void HelloWorld::myThreadB()
{
while(true)
{
if (tickets>0)
{
Sleep(10);
CCLOG("B Sell %d",tickets--);
}
else
{
break;
}
}
}

代码非常easy。不多说了。我们来看一下输出。会发现有非常多喜闻乐见的现象出现。由于每一个人每次执行的结果都不一样。所以这里不贴结果了,当中比較有意思的现象是同一张票卖了两次?!
原因不多解释了,时间片的问题,不明确的Google之。

假设你认为不会有这么巧,那么在打印结果前加上这么一句:

Sleep(100);

执行结果如图所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3RhcjUzMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

3.利用相互排斥对象同步数据
这个问题主要是由于一个线程执行到一半的时候,时间片的切换导致还有一个线程改动了同一个数据,当再次切换会原来线程并继续往下执行的时候,数据由于被改动了导致结果出错。

所以我们要做的就是保证这个线程全然执行完。所以对线程加锁是个不错的注意,相互排斥对象mutex就是这个锁。
3.1、初始化相互排斥锁

std::mutex mutex;//线程相互排斥对象

3.2、改动myThreadA与myThreadB的代码,在里面加入相互排斥锁

void HelloWorld::myThreadA()
{
while(true)
{
mutex.lock();//加锁
if(tickets>0)
{
Sleep(10);
CCLOG("A Sell %d",tickets--);//输出售票。每次减1
mutex.unlock();//解锁
}
else {
mutex.unlock();
break; }
}
}
void HelloWorld::myThreadB()
{
while(true)
{
mutex.lock();
if (tickets>0)
{
Sleep(10);
CCLOG("B Sell %d",tickets--);
mutex.unlock();
}
else
{
mutex.unlock();
break;
}
}
}

执行结果例如以下。完美

使用std::mutex有一个要注意的地方:在线程A中std::mutex使用成员函数lock加锁unlock解锁,看起来工作的非常好,但这样是不安全的,你得始终记住lock之后一定要unlock。可是假设在它们中间出现了异常或者线程直接退出了unlock就没有执行,由于这个相互排斥量是独占式的。所以在threadA没有解锁之前,其它使用这个相互排斥量加锁的线程会一直处于等待状态得不到执行

恩,就写到这里。

嘿嘿嘿嘿。

尊重原创,转载请注明来源:http://blog.csdn.net/star530/article/details/24187103

Cocos2dx 3.0 过渡篇(二十七)C++11多线程std::thread的简单使用(下)的更多相关文章

  1. Cocos2dx 3.0 过渡篇(二十六)C++11多线程std::thread的简单使用(上)

    昨天练车时有一MM与我交替着练,聊了几句话就多了起来,我对她说:"看到前面那俩教练没?老色鬼两枚!整天调戏女学员."她说:"还好啦,这毕竟是他们的乐趣所在,你不认为教练每 ...

  2. Cocos2dx 3.0 过渡篇(三十)灰机还是3D好(Sprite3D)

    如今都非常少发3.0过渡篇这一系列的博文了,原因是多方面的,一个是游戏开发进度,尽管上面并没给我什么压力,但我自己一直在赶.还有一方面是个人私生活这块.五月份确实是多事之秋,有时候真的没办法全心思去研 ...

  3. Cocos2dx 3.0 过渡篇(二十八)C++11强类型枚举

    一朋友在微信朋友圈晒了张照片,随手点开大图,带着赞赏的眼光扫了下,恩,几个月不见.又美丽了...咦?等等,她戴的这是什么?酷炫的造型! 金属边框! 微型摄像头! 这不是传说中的谷歌眼镜么?土豪啊,还好 ...

  4. Cocos2dx 3.0 过渡篇(三十一)ValueVector和Vector不得不说的故事

    本文投票地址:http://vote.blog.csdn.net/Article/Details?articleid=37834689 前天看到一个颇为纠结的选择题:有一天你遇到一个外星人,这时外星人 ...

  5. Cocos2dx 3.0 过渡篇(二十九)globalZOrder()与localZOrder()

    前天非常难得的加班到八点...为什么说难得呢?由于平时我差点儿就没加班过.六点下班后想走就走,想留就留.率直洒脱.不拘一格.尽显男儿本色.程序猿,就是这么自信! -----------这篇博客的标题本 ...

  6. Cocos2dx 3.0 过渡篇(二十五)死不了的贪食蛇(触摸版)

    上一篇写的贪食蛇的重力感应控制版,这一篇就讲下触摸控制版吧.额,也不知道写了那个贪食蛇教程究竟有没有获得沈老师的书,假设没有的话,看我不拿西瓜刀砍掉 偶尔E往事 的那啥! 重力版链接:http://b ...

  7. Cocos2dx 3.0 交流篇

    创建项目: For(MAC) Runtime Requirements Android 2.3 or newer iOS 5.0 or newer OS X 10.7 or newer Windows ...

  8. Cocos2dx3.0过渡篇 各种遍历与范围for语句的使用【转】

    1.CCArray的遍历看到这里,有些人又按耐不住的要举起西瓜刀了:你不是说3.0beta后已经没有CCArray这货了吗?现在又拿出来作甚?其实我也很无辜,CCArray确实是没了,但在某个不为人知 ...

  9. Cocos2dx3.0过渡篇 globalZOrder()与localZOrder()

    这篇博客的标题本想叫“...3.0新的渲染...介绍”,最后还是拉不下这个脸.为啥?觉得自己对渲染的认识还是过于表面,谈不上理解.当然了,这并不影响这篇博客继续写下去.下面看一段3.0Release ...

随机推荐

  1. 创建 python 虚拟环境

    conda 创建环境 conda 可以理解为一个工具,也是一个可执行命令,其核心功能是包管理与环境管理.包管理与 pip 的使用类似,环境管理则允许用户方便地安装不同版本的 python 并可以快速切 ...

  2. python 关键知识点

    学习资源:笨方法学习 python3 将变量传递给脚本--argv 脚本:你编写的 .py 文件. argv 参数变量(argument variable)保存着你运行 python 脚本的参数. i ...

  3. 这套完美的Java环境安装教程,完整,详细,清晰可观,让你一目了然,简单易懂。⊙﹏⊙

    JDK下载与安装教程 2017年06月18日 22:53:16 Danishlyy1995 阅读数:349980  版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  4. ACM 水果 hdu 1263 一题多解

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1263 文章末有相应的一些测试数据供参考. 传统的数组解题方式 思路一: 三种属性的数据放在一个结构体里面, ...

  5. Python 递归删除非空目录(包括子目录以及文件)

    Python的OS模块自带rmdir和removedirs函数用于删除目录,但是两者都不能删除非空目录,以下代码定义了一个函数 remove_dir 用于删除非空目录. #作者官网 http://ww ...

  6. [ 转载 ] Java基础4--Java中的static关键字解析

    Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...

  7. touchscreem

    <触摸屏种类> 常见 电阻式触摸屏 电容式触摸屏 不常见 红外线技术触摸屏 表面声波触摸屏 适量压力传感触摸屏 <原理分析> 电阻式触摸屏 如图所示,在屏幕的上下和左右加上一个 ...

  8. Python 面向对象编程——访问限制

    <无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...

  9. POJ 2117 Electricity 双联通分量 割点

    http://poj.org/problem?id=2117 这个妹妹我竟然到现在才见过,我真是太菜了~~~ 求去掉一个点后图中最多有多少个连通块.(原图可以本身就有多个连通块) 首先设点i去掉后它的 ...

  10. 【POJ】1862:Stripies【贪心】【优先队列】

    Stripies Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 20456   Accepted: 9098 Descrip ...