溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Cocos2d-x 3.x中的多線程基本實現(xiàn)思路

發(fā)布時間:2020-08-14 00:00:27 來源:網(wǎng)絡(luò) 閱讀:997 作者:googlingman 欄目:游戲開發(fā)

        當(dāng)前正在改寫一個基于早期Cocos2d-x 2.x實現(xiàn)的小游戲,在涉及到多線程代碼時,忽然編譯器提示找不到頭文件pthread.h。查了一下,發(fā)現(xiàn)如今的3.x中不再支持pthread.h頭文件,以前的2.X時代這個文件包含在$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread路徑下。

    現(xiàn)在,3.X中推薦直接使用std::thread相關(guān)API,當(dāng)然是經(jīng)過C++ 11簡化處理后的多線程API。

 

  總體使用思路歸納如下:


--------------------------------------------------------------------------------

 

      在cocos2d-x 2.0時代,我們使用的是pthread庫,是一套用戶級線程庫,被廣泛地使用在跨平臺應(yīng)用上。但在cocos2d-x 3.0中并未發(fā)現(xiàn)有pthread的支持文件,原來C++11中已經(jīng)擁有了一個更好用的用于線程操作的類std::thread。cocos2d-x 3.0的版本默認(rèn)是在vs2012版本,支持C++11的新特性,使用std::thread來創(chuàng)建線程簡直方便。

 

下面介紹下std::thread的一下簡單用法,代碼需包含頭文件<thread>。

 

bool HelloWorld::init()   
{   
    if ( !Layer::init() )   
    {   
        return false;   
    }   
        
    std::thread t1(&HelloWorld::myThread,this);//創(chuàng)建分支線程,回調(diào)到myThread函數(shù)里   
    t1.join();   
//  t1.detach();   
    
    CCLOG("in major thread");//在主線程   
    
    return true;   
}   
    
void HelloWorld::myThread()   
{   
    CCLOG("in my thread");   
}

--------------------------------------------------------------------------------

 解釋

  t.join()等待子線程myThread執(zhí)行完之后,主線程才可以繼續(xù)執(zhí)行下去,此時主線程會釋放掉執(zhí)行完后的子線程資源。從上面的圖片也可以看出,是先輸出"in my thread",再輸出"in major thread"。

 

  當(dāng)然了,如果不想等待子線程,可以在主線程里面執(zhí)行t1.detach()將子線程從主線程里分離,子線程執(zhí)行完成后會自己釋放掉資源。分離后的線程,主線程將對它沒有控制權(quán)了。如下:

 

std::thread t1(&HelloWorld::myThread,this);//創(chuàng)建一個分支線程,回調(diào)到myThread函數(shù)里  
t1.detach();
--------------------------------------------------------------------------------

  當(dāng)然了,也可以往線程函數(shù)里穿參數(shù),這里用到了bind。下面例子在實例化線程對象的時候,在線程函數(shù)myThread后面緊接著傳入兩個參數(shù)。

 

bool HelloWorld::init()   
    {   
        if ( !Layer::init() )   
        {   
            return false;   
        }   
            
        std::thread t1(&HelloWorld::myThread,this,10,20);//創(chuàng)建一個分支線程,回調(diào)到myThread函數(shù)里   
        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);   
    }

 

--------------------------------------------------------------------------------

 

利用互斥對象同步數(shù)據(jù)

 

  這個問題主要是因為一個線程執(zhí)行到一半的時候,時間片的切換導(dǎo)致另一個線程修改了同一個數(shù)據(jù),當(dāng)再次切換會原來線程并繼續(xù)往下運行的時候,數(shù)據(jù)由于被修改了導(dǎo)致結(jié)果出錯。所以我們要做的就是保證這個線程完全執(zhí)行完,所以對線程加鎖是個不錯的注意,互斥對象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使用成員函數(shù)lock加鎖unlock解鎖,看起來工作的很好,但這樣是不安全的,你得始終記住lock之后一定要unlock,但是如果在它們中間出現(xiàn)了異?;蛘呔€程直接退出了unlock就沒有執(zhí)行,因為這個互斥量是獨占式的,所以在threadA沒有解鎖之前,其他使用這個互斥量加鎖的線程會一直處于等待狀態(tài)得不到執(zhí)行。


  上面總結(jié)的僅是C++ 11支持下的實現(xiàn)多線程編程的基本情況,在涉及到比簡單互斥鎖更復(fù)雜的情況沒有討論。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI