C++11多執行緒std::thread的簡單使用
在cocos2dx 2.0時代,我們使用的是pthread庫,是一套使用者級執行緒庫,被廣泛地使用在跨平臺應用上。但在cocos2dx 3.0中並未發現有pthread的支援檔案,原來c++11中已經擁有了一個更好用的用於執行緒操作的類std::thread。cocos2dx 3.0的版本預設是在vs2012版本,支援c++11的新特性,使用std::thread來建立執行緒簡直方便。
下面介紹下std::thread的一下簡單用法,程式碼需包含標頭檔案<thread>
bool HelloWorld::init() { if ( !Layer::init() ) {return false; } std::thread t1(&HelloWorld::myThread,this);//建立一個分支執行緒,回撥到myThread函式裡 t1.join(); // t1.detach(); CCLOG("in major thread");//在主執行緒 return true; } void HelloWorld::myThread() { CCLOG("in my thread"); }
執行結果如下圖:
t.join()等待子執行緒myThread執行完之後,主執行緒才可以繼續執行下去,此時主執行緒會釋放掉執行完後的子執行緒資源
當然了,如果不想等待子執行緒,可以在主執行緒裡面執行t1.detach()將子執行緒從主執行緒裡分離,子執行緒執行完成後會自己釋放掉資源。分離後的執行緒,主執行緒將對它沒有控制權了。如下:
std::thread t1(&HelloWorld::myThread,this);//建立一個分支執行緒,回撥到myThread函式裡 t1.detach();
執行結果如下:
當然了,也可以往執行緒函式裡穿引數,這裡用到了bind。下面例子在例項化執行緒物件的時候,線上程函式myThread後面緊接著傳入兩個引數。
bool HelloWorld::init() { if ( !Layer::init() ) { return false; } std::thread t1(&HelloWorld::myThread,this,10,20);//建立一個分支執行緒,回撥到myThread函式裡 t1.join(); // t1.detach(); CCLOG("in major thread");//在主執行緒 return true; } void HelloWorld::myThread(int first,int second) { CCLOG("in my thread,first = %d,second = %d",first,second); }
輸出結果如下圖:
例項:
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; } } }
程式碼很簡單,不多說了。我們來看一下輸出,會發現有很多喜聞樂見的現象出現,因為每個人每次執行的結果都不一樣,所以這裡不貼結果了,其中比較有意思的現象是同一張票賣了兩次?!
原因不多解釋了,時間片的問題,不明白的Google之。如果你覺得不會有這麼巧,那麼在列印結果前加上這麼一句:
Sleep(100);
執行結果如圖所示:
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沒有解鎖之前,其他使用這個互斥量加鎖的執行緒會一直處於等待狀態得不到執行
相關推薦
C++11多執行緒std::thread的簡單使用
在cocos2dx 2.0時代,我們使用的是pthread庫,是一套使用者級執行緒庫,被廣泛地使用在跨平臺應用上。但在cocos2dx 3.0中並未發現有pthread的支援檔案,原來c++11中已經擁有了一個更好用的用於執行緒操作的類std::thread。cocos
一、C++11多執行緒std::thread的簡單使用(上)
出處:http://blog.csdn.net/star530/article/details/24186783 昨天練車時有一MM與我交替著練,聊了幾句話就多了起來,我對她說:”看到前面那倆教練沒?老色鬼兩枚!整天調戲女學員。“她說:”還好啦,這畢竟是他們的樂趣所在,你不
Cocos2dx 3.0 過渡篇(二十六)C++11多執行緒std::thread的簡單使用
--------------- 《上》 本篇介紹的是執行緒! 在cocos2dx 2.0時代,我們使用的是pthread庫,是一套使用者級執行緒庫,被廣泛地使用在跨平臺應用上。但在cocos2dx 3.0中並未發現有pthread的支援檔案,原來c++11中已經擁有了一
C++11多執行緒------std::async
std::async可以認為是封裝了一個std::promise,該函式返回一個std::future,用於獲取其他執行緒的資料。 一般有兩種模式: std::lanch::async:最常用的非同步模式,每次都要執行一遍 std::lanch::defer:只在第
C++11 多執行緒gcc編譯簡單示例
1. 編輯源程式 vim hello.cpp #include <iostream> #include <thread> void func(int x) { std::cout << x << "
C++11 多執行緒學習----std::thread類的簡單使用
一 C++11多執行緒簡介 C++11標準庫會提供類thread(std::thread)。若要執行一個執行緒,可以建立一個類thread的實體,其初始引數為一個函式物件,以及該函式物件所需要的
Cocos2dx 3.0 過渡篇(二十七)C++11多線程std::thread的簡單使用(下)
fonts fun avi 2dx read 來源 cpp break 輸出 本篇接上篇繼續講:上篇傳送門:http://blog.csdn.net/star530/article/details/24186783簡單的東西我都說的幾乎相同了,想挖點深的差點把自己給填進
c++11多執行緒 thread
1.thread建構函式 default (1) thread() noexcept; initialization (2) template <class Fn, class... Args> explicit
C++ 11 多執行緒下std::unique_lock與std::lock_guard的區別和用法
這裡主要介紹std::unique_lock與std::lock_guard的區別用法 先說簡單的 一、std::lock_guard的用法 std::lock_guard其實就是簡單的RAII封裝,在建構函式中進行加鎖,解構函式中進行解鎖,這樣可以保證函式退出時,鎖一定被釋放。 簡單來說,就是防止開
C++11多執行緒程式設計 第九章: std::async 更更優雅的寫多執行緒
C++11 Multithreading – Part 9: std::async Tutorial & Example Varun May 5, 2017 C++11 Multithreading – Part 9: std::async Tutorial &
C++11多執行緒程式設計 第八章: 使用 std::future std::promise 更優雅的獲取執行緒返回值
C++11 Multithreading – Part 8: std::future , std::promise and Returning values from Thread Varun June 20, 2015 C++11 Multithreading – Part
c++11多執行緒:std::future , std::promise和執行緒的返回值
std::future物件可以和asych,std::packaged_task,std::promise一起使用。這篇文章集中討論std::future和std::promise。 我們經常會遇到需要得到執行緒返回結果的情況,現在的問題是我們如何實現。 舉個例子: 假設
C++11多執行緒(十一):《atomic型別詳解二:std::atomic》
參考連結: http://www.cnblogs.com/haippy/p/3301408.html 不錯的部落格 http://www.cplusplus.com/reference/future/future/ cplusplus官網 目錄 1.std::atomic 基本介紹 2.std::atomic
C++11多執行緒thread引數傳遞問題
目錄 寫在前面 thread類的建構函式 join函式 detach函式 thread中引數傳遞 類物件作為引數 類中函式作為引數 參考書籍 寫在前面 多執行緒在很多地方都是必須要掌握的方法,這裡先說一下,thread物件的引數傳遞問題 thread類
C++11多執行緒(七):《 詳解三:std::future & std::shared_future》
#include <iostream> // std::cout #include <future> // std::async, std::future #include <chrono>
C++11多執行緒(十一):《atomic 型別詳解三 std::atomic (續)》
參考連結:http://www.cnblogs.com/haippy/p/3304556.html 本文介紹C++11 標準庫中的 std::atomic 針對整形(integral)和指標型別的特化版本做了哪些改進。
[轉]c++11 多執行緒 future/promise
[轉自 https://blog.csdn.net/jiange_zh/article/details/51602938] 1. < future >標頭檔案簡介 Classes std::future std::future_error std::packaged_task std::pro
C++11 多執行緒執行緒共享資料
共享資料的問題 這些在作業系統中都有詳細的介紹,可以回顧作業系統課程。。很典型的就是資料競爭問題。 互斥量保護資料 最原始的方式:使用std::mutex建立互斥量,使用成員lock()加鎖,使用成員unlock()解鎖。但是這種方式需要我們在每個函數出口都呼叫一次unloc
c++11多執行緒與執行緒池
最近需要開發一個高效能運算庫,涉及到c++多執行緒的應用,上次做類似的事情已經是4年多以前了,印象中還頗有些麻煩。悔當初做了就算了,也沒想著留點記錄什麼的。這次又研究了一番,發現用上c++11特性之後,現在已經比較簡單了,在此記錄一下。 最簡單的多執行緒情況,不涉及公共變數,各個執行緒之間獨
利用C++11實現執行緒task的簡單封裝
#include <functional> #include <thread> #include <type_traits> /*Compile only if 'F' is callable. F maybe function, la