您好,登錄后才能下訂單哦!
當前正在改寫一個基于早期Cocos2d-x 2.x實現的小游戲,在涉及到多線程代碼時,忽然編譯器提示找不到頭文件pthread.h。查了一下,發現如今的3.x中不再支持pthread.h頭文件,以前的2.X時代這個文件包含在$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread路徑下。
現在,3.X中推薦直接使用std::thread相關API,當然是經過C++ 11簡化處理后的多線程API。
總體使用思路歸納如下:
--------------------------------------------------------------------------------
在cocos2d-x 2.0時代,我們使用的是pthread庫,是一套用戶級線程庫,被廣泛地使用在跨平臺應用上。但在cocos2d-x 3.0中并未發現有pthread的支持文件,原來C++11中已經擁有了一個更好用的用于線程操作的類std::thread。cocos2d-x 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執行完之后,主線程才可以繼續執行下去,此時主線程會釋放掉執行完后的子線程資源。從上面的圖片也可以看出,是先輸出"in my thread",再輸出"in major thread"。
當然了,如果不想等待子線程,可以在主線程里面執行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); }
--------------------------------------------------------------------------------
利用互斥對象同步數據
這個問題主要是因為一個線程執行到一半的時候,時間片的切換導致另一個線程修改了同一個數據,當再次切換會原來線程并繼續往下運行的時候,數據由于被修改了導致結果出錯。所以我們要做的就是保證這個線程完全執行完,所以對線程加鎖是個不錯的注意,互斥對象mutex就是這個鎖。
1)初始化互斥鎖
std::mutex mutex;//線程互斥對象
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支持下的實現多線程編程的基本情況,在涉及到比簡單互斥鎖更復雜的情況沒有討論。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。