Cocos2dx 3.0 过渡篇(二十七)C++11多线程std::thread的简单使用(下)
本篇接上篇继续讲:上篇传送门: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的简单使用(下)的更多相关文章
- Cocos2dx 3.0 过渡篇(二十六)C++11多线程std::thread的简单使用(上)
昨天练车时有一MM与我交替着练,聊了几句话就多了起来,我对她说:"看到前面那俩教练没?老色鬼两枚!整天调戏女学员."她说:"还好啦,这毕竟是他们的乐趣所在,你不认为教练每 ...
- Cocos2dx 3.0 过渡篇(三十)灰机还是3D好(Sprite3D)
如今都非常少发3.0过渡篇这一系列的博文了,原因是多方面的,一个是游戏开发进度,尽管上面并没给我什么压力,但我自己一直在赶.还有一方面是个人私生活这块.五月份确实是多事之秋,有时候真的没办法全心思去研 ...
- Cocos2dx 3.0 过渡篇(二十八)C++11强类型枚举
一朋友在微信朋友圈晒了张照片,随手点开大图,带着赞赏的眼光扫了下,恩,几个月不见.又美丽了...咦?等等,她戴的这是什么?酷炫的造型! 金属边框! 微型摄像头! 这不是传说中的谷歌眼镜么?土豪啊,还好 ...
- Cocos2dx 3.0 过渡篇(三十一)ValueVector和Vector不得不说的故事
本文投票地址:http://vote.blog.csdn.net/Article/Details?articleid=37834689 前天看到一个颇为纠结的选择题:有一天你遇到一个外星人,这时外星人 ...
- Cocos2dx 3.0 过渡篇(二十九)globalZOrder()与localZOrder()
前天非常难得的加班到八点...为什么说难得呢?由于平时我差点儿就没加班过.六点下班后想走就走,想留就留.率直洒脱.不拘一格.尽显男儿本色.程序猿,就是这么自信! -----------这篇博客的标题本 ...
- Cocos2dx 3.0 过渡篇(二十五)死不了的贪食蛇(触摸版)
上一篇写的贪食蛇的重力感应控制版,这一篇就讲下触摸控制版吧.额,也不知道写了那个贪食蛇教程究竟有没有获得沈老师的书,假设没有的话,看我不拿西瓜刀砍掉 偶尔E往事 的那啥! 重力版链接:http://b ...
- Cocos2dx 3.0 交流篇
创建项目: For(MAC) Runtime Requirements Android 2.3 or newer iOS 5.0 or newer OS X 10.7 or newer Windows ...
- Cocos2dx3.0过渡篇 各种遍历与范围for语句的使用【转】
1.CCArray的遍历看到这里,有些人又按耐不住的要举起西瓜刀了:你不是说3.0beta后已经没有CCArray这货了吗?现在又拿出来作甚?其实我也很无辜,CCArray确实是没了,但在某个不为人知 ...
- Cocos2dx3.0过渡篇 globalZOrder()与localZOrder()
这篇博客的标题本想叫“...3.0新的渲染...介绍”,最后还是拉不下这个脸.为啥?觉得自己对渲染的认识还是过于表面,谈不上理解.当然了,这并不影响这篇博客继续写下去.下面看一段3.0Release ...
随机推荐
- MyBatis-Plus 3.0.7.1
1 .分页配置 <plugins> <plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInte ...
- iOS开发之app打包发布流程
一.准备工作 苹果开发者中心 1.申请苹果开发者账号 首先需要申请苹果开发者账号才能在APP store 里发布应用. 开发者账号分类:(1)个人开发者账号 (2)企业开发者账号 主要的区别是:点击这 ...
- [CodeForces]CodeForces 13D 几何 思维
大致题意: 给出N个红点和M个蓝点,问可以有多少个红点构成的三角形,其内部不含有蓝点 假设我们现在枚举了一条线段(p[i],p[j]),我们可以记录线段下方满足(min(p[i].x,p[j].x)& ...
- 深度学习---手写字体识别程序分析(python)
我想大部分程序员的第一个程序应该都是“hello world”,在深度学习领域,这个“hello world”程序就是手写字体识别程序. 这次我们详细的分析下手写字体识别程序,从而可以对深度学习建立一 ...
- Java工具类之浮点精确计算
public class Arith { // 默认除法运算精度 private static final int DEF_DIV_SCALE = 10; // 构造器私有,让这个类不能实例化 pri ...
- 深入理解Python生成器(Generator)
我们可以通过列表生成式简单直接地创建一个列表,但是受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,而且如果我们仅仅需要访问前面几个元素,那后面绝大多 ...
- 工作中怎么解决bug
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 1,看日志 2,看日志解决不了,断点调试 3,网络搜索.
- [NOI2018]你的名字(SAM+线段树合并)
考虑l=1,r=n的68分,对S和T建SAM,对T的SAM上的每个节点,计算它能给答案带来多少贡献. T上节点x代表的本质不同的子串数为mx[x]-mx[fa[x]],然后需要去掉所代表子串与S的最长 ...
- 【推导】The 16th UESTC Programming Contest Preliminary L - Foxtrot
题意:有n瓶药剂,其中只有一瓶药剂有毒.让你用最少的小白鼠试出哪瓶有毒.你只有一次给任意只小白鼠各喂食任意种类药剂的机会. m只老鼠就能对应2^m种“生死状态”的组合,给每种状态分配一个种类的药剂,然 ...
- 【差分约束系统/DFS版SPFA】BZOJ3436-小K的农场
[题目大意] 总共n个农场,有以下三种描述:农场a比农场b至少多种植了c个单位的作物,农场a比农场b至多多种植了c个单位的作物,农场a与农场b种植的作物数一样多.问是否有可能性. [思路] 农场a比农 ...