青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 132  文章 - 51  trackbacks - 0
<2012年7月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用鏈接

留言簿(7)

隨筆分類

隨筆檔案

文章分類

文章檔案

cocos2d-x

OGRE

OPenGL

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

多個線程操作相同的數據時,一般是需要按順序訪問的,否則會引導數據錯亂,無法控制數據,變成隨機變量。為解決這個問題,就需要引入互斥變量,讓每個線程都按順序地訪問變量。這樣就需要使用EnterCriticalSection和LeaveCriticalSection函數

有人比如的很形象:
就像上廁所:
門鎖了,就等著,等到別人出來了,進去鎖上,然后該干什么干什么,干完了,把門打開

門沒鎖,就進去,鎖上,然后該干什么干什么,干完了,把門打開

--------------------------------------------------
多線程中用來確保同一時刻只有一個線程操作被保護的數據

InitializeCriticalSection(&cs);//初始化臨界區
EnterCriticalSection(&cs);//進入臨界區
//操作數據
MyMoney*=10;//所有訪問MyMoney變量的程序都需要這樣寫Enter.. Leave...
LeaveCriticalSection(&cs);//離開臨界區
DeleteCriticalSection(&cs);//刪除臨界區

實際遇到的問題:如多線程加載紋理過程中遇到的問題
step1.創建全局互斥變量,并初始化 
    
static CRITICAL_SECTION gs_TextureLoadingCS;            //全局互斥變量
    static std::vector<CHRTextureLoadingReq> gs_TextureLoadingReqs;        //全局紋理容器命令
    
    CHRTextureMgrInstance::CHRTextureMgrInstance()
    
{
        InitializeCriticalSection( 
&gs_TextureLoadingCS );
    }


    CHRTextureMgrInstance::
~CHRTextureMgrInstance()
    
{
        DeleteCriticalSection( 
&gs_TextureLoadingCS );
    }


step2.開啟加載紋理多線程
BOOL CHRTextureMgrInstance::StartTextureLoadingThread()
{
    gs_bTextureMgrWillDestroy 
= FALSE;
    gs_bTextureLoadingThreadTerminated 
= FALSE;
    
//InitializeCriticalSection( &gs_TextureLoadingCS );
    _beginthread( TextureLoadingThread, NULL, GetHREngine()->GetRenderer()->GetRealDevice() );  //開啟加載紋理線程
    return TRUE;
}


void TextureLoadingThread(void* p)
{
//    LPDIRECT3DDEVICE8 pD3DDevice = (LPDIRECT3DDEVICE8)p;
    IHRRenderer* RI = GetHREngine()->GetRenderer();
    
// 當主線程要結束了
    while!gs_bTextureMgrWillDestroy )
    
{
        CHRTextureLoadingReq req;
        BOOL bHasReq 
= FALSE;
        EnterCriticalSection( 
&gs_TextureLoadingCS );                            //進入臨界區
        if( gs_TextureLoadingReqs.size() > 0 )                                    //操作,取出一個紋理加載
        {
            bHasReq 
= TRUE;
            req 
= gs_TextureLoadingReqs[0];
            gs_TextureLoadingReqs.erase( gs_TextureLoadingReqs.begin() );
        }

        LeaveCriticalSection( 
&gs_TextureLoadingCS );                            //離開臨界區 
        if( bHasReq )
        
{
            
if( CreateTextureFromReq( RI, &req ) )
            
{
                PostTextureLoadingAck( req );
            }

        }

        Sleep( 
1 );
    }

    
// 這個線程結束了
    gs_bTextureLoadingThreadTerminated = TRUE;
}


step2.讀取圖片并壓入容器,邊壓入,邊讀取

    g_nGlobalTextures[eFootprint]    
= pMgr->RegisterTexture( "Data\\Textures\\Effect\\Footprint.tga", TRUE, 0, TRUE );
    g_nGlobalTextures[eSmoke]        
= pMgr->RegisterTexture( "Data\\Textures\\Effect\\Smoke.tga", TRUE, 0, TRUE );
    g_nGlobalTextures[eShadow]        
= pMgr->RegisterTexture( "Data\\Textures\\Effect\\Shadow.tga", TRUE, 0, TRUE );
    g_nGlobalTextures[eHitFlash]    
= pMgr->RegisterTexture( "Data\\Textures\\Effect\\HitFlash.tga", TRUE, 0, TRUE );
    g_nGlobalTextures[eElectric]    
= pMgr->RegisterTexture( "Data\\Textures\\Effect\\LightingRed.tga", TRUE, 0, TRUE );
    
    BOOL PostTextureLoadingReq( CHRTextureLoadingReq
& req )
    
{
        EnterCriticalSection( 
&gs_TextureLoadingCS );
        gs_TextureLoadingReqs.push_back( req );
        LeaveCriticalSection( 
&gs_TextureLoadingCS );
        
return TRUE;
    }




舉個簡單的例子:
#include "stdafx.h"
#include 
<Windows.h>
#include 
<iostream>
#include 
<process.h>
using std::cout;
using std::endl;


CRITICAL_SECTION cs;
UINT n_AddValue  
= 0;

// first thread
void FirstThread( LPVOID lParam )
{
    
forint i = 0; i < 100; i++ ){
        EnterCriticalSection( 
&cs );
        n_AddValue
++;
        cout 
<< "n_AddValue in FirstThread is "<<n_AddValue <<endl;
        LeaveCriticalSection( 
&cs );
    }

}


// second thread
void  SecondThread( LPVOID lParam )
{
    
forint i = 0; i < 100; i++ ){
        EnterCriticalSection( 
&cs );    
        n_AddValue
++;
        cout 
<< "n_AddValue in SecondThread is "<<n_AddValue <<endl;
        LeaveCriticalSection( 
&cs );
    }


}



void main()
{
    InitializeCriticalSection( 
&cs );
    
    HANDLE hThread[
2];
    hThread[
0= (HANDLE)_beginthread( FirstThread, 0, LPVOID(NULL) );
    hThread[
1= (HANDLE)_beginthread( SecondThread, 0, LPVOID(NULL) );
    
    
// 等待線程返回
    WaitForMultipleObjects( 2, hThread, true, INFINITE );

    DeleteCriticalSection( 
&cs );
    system(
"pause");
}


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
臨界區的理解:

理解EnterCriticalSection 臨界區

 

 

比如說我們定義了一個共享資源dwTime[100],兩個線程ThreadFuncA和ThreadFuncB都對它進行讀寫操作。當我們想要保證 dwTime[100]的操作完整性,即不希望寫到一半的數據被另一個線程讀取,那么用CRITICAL_SECTION來進行線程同步如下:

第一個線程函數:

DWORD   WINAPI   ThreadFuncA(LPVOID   lp)
{
EnterCriticalSection(&cs);
...
//   操作dwTime
...
LeaveCriticalSection(&cs);
return   0;
}

寫出這個函數之后,很多初學者都會錯誤地以為,此時cs對dwTime進行了鎖定操作,dwTime處于cs的保護之中。一個“自然而然”的想法就是——cs和dwTime一一對應上了。

這么想,就大錯特錯了。dwTime并沒有和任何東西對應,它仍然是任何其它線程都可以訪問的。如果你像如下的方式來寫第二個線程,那么就會有問題:

DWORD   WINAPI   ThreadFuncB(LPVOID   lp)
{
...
//   操作dwTime
...
return   0;
}

當線程ThreadFuncA執行了EnterCriticalSection(&cs),并開始操作dwTime[100]的時候,線程 ThreadFuncB可能隨時醒過來,也開始操作dwTime[100],這樣,dwTime[100]中的數據就被破壞了。

為了讓CRITICAL_SECTION發揮作用,我們必須在訪問dwTime的任何一個地方都加上 EnterCriticalSection(&cs)和LeaveCriticalSection(&cs)語句。所以,必須按照下面的方式來寫第二個線程函數:

DWORD   WINAPI   ThreadFuncB(LPVOID   lp)
{
EnterCriticalSection(&cs);
...
//   操作dwTime
...
LeaveCriticalSection(&cs);
return   0;
}

這樣,當線程ThreadFuncB醒過來時,它遇到的第一個語句是EnterCriticalSection(&cs),這個語句將對cs變量進行訪問。如果這個時候第一個線程仍然在操作dwTime[100],cs變量中包含的值將告訴第二個線程,已有其它線程占用了cs。因此,第二個線程的 EnterCriticalSection(&cs)語句將不會返回,而處于掛起等待狀態。直到第一個線程執行了 LeaveCriticalSection(&cs),第二個線程的EnterCriticalSection(&cs)語句才會返回,并且繼續執行下面的操作。

這個過程實際上是通過限制有且只有一個函數進入CriticalSection變量來實現代碼段同步的。簡單地說,對于同一個 CRITICAL_SECTION,當一個線程執行了EnterCriticalSection而沒有執行LeaveCriticalSection的時候,其它任何一個線程都無法完全執行EnterCriticalSection而不得不處于等待狀態

再次強調一次,沒有任何資源被“鎖定”,CRITICAL_SECTION這個東東不是針對于資源的,而是針對于不同線程間的代碼段的!我們能夠用它來進行所謂資源的“鎖定”,其實是因為我們在任何訪問共享資源的地方都加入了EnterCriticalSection和 LeaveCriticalSection語句,使得同一時間只能夠有一個線程的代碼段訪問到該共享資源而已(其它想訪問該資源的代碼段不得不等待)。

這就是使用一個CRITICAL_SECTION時的情況。你應該要知道,它并沒有什么可以同步的資源的“集合”。這個概念不正確。

如果是兩個CRITICAL_SECTION,就以此類推。

 

雖然臨界區同步速度很快,但卻能用來同步本進程內的線程,而不可用來同步多個進程中的線程

    MFC提供了很多功能完備的類,我用MFC實現了臨界區。MFC為臨界區提供有一個CCriticalSection類,使用該類進行線程同步處理是非常簡單的。只需在線程函數中用CCriticalSection類成員函數Lock()和UnLock()標定出被保護代碼片段即可。Lock()后代碼用到的資源自動被視為臨界區內的資源被保護。UnLock后別的線程才能訪問這些資源。

posted on 2010-07-08 10:39 風輕云淡 閱讀(1859) 評論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久电影一区| 欧美激情精品久久久六区热门 | 麻豆av福利av久久av| 亚洲欧美资源在线| 午夜电影亚洲| 久久久久久久久久久成人| 久久久亚洲精品一区二区三区| 久久蜜桃av一区精品变态类天堂| 久久久福利视频| 欧美精品一区二区蜜臀亚洲| 欧美日韩国产色综合一二三四| 欧美日韩视频在线一区二区| 欧美网站大全在线观看| 国产日韩欧美精品| 亚洲福利电影| 亚洲视频在线一区观看| 久久高清福利视频| 欧美成人中文| 亚洲天堂免费观看| 久久久久高清| 国产精品国产三级国产普通话三级 | 久久野战av| 亚洲国产网站| 亚洲一区二区视频在线| 久久香蕉国产线看观看av| 欧美人与禽猛交乱配视频| 国产女精品视频网站免费| 亚洲成人直播| 欧美一区二区在线观看| 亚洲高清激情| 欧美一区二区精品久久911| 欧美国产日本在线| 国产偷久久久精品专区| 夜夜嗨av色一区二区不卡| 久久综合精品一区| 亚洲无线视频| 欧美日一区二区三区在线观看国产免| 国产亚洲欧美aaaa| 在线视频精品一区| 欧美成人日韩| 久久国产精品久久久| 国产精品扒开腿爽爽爽视频 | 亚洲丰满在线| 久久久免费av| 亚洲免费视频成人| 欧美日韩在线视频一区| 国产精品久久久久久av下载红粉 | 欧美日韩亚洲一区二区三区在线观看| 久久久伊人欧美| 欧美国产精品久久| 国产色综合久久| 亚洲欧洲一区二区在线播放| 免费不卡视频| 香蕉成人久久| 欧美成人中文字幕在线| 欧美一区二区三区电影在线观看| 欧美日韩国产一级| 亚洲美女在线一区| 亚洲国产精品ⅴa在线观看| 午夜精品一区二区三区在线播放| 欧美天天视频| 亚洲欧美不卡| 中文网丁香综合网| 国产精品vip| 性欧美暴力猛交69hd| 亚洲午夜精品一区二区| 欧美午夜精品久久久久久超碰| 亚洲麻豆视频| 一本色道久久88综合日韩精品| 欧美精品一线| 亚洲一区二区三区视频播放| 99热精品在线| 国产精品嫩草影院av蜜臀| 欧美激情一区二区三区蜜桃视频| 久久国产婷婷国产香蕉| 亚洲欧美www| 午夜日韩av| 国产亚洲欧美日韩日本| 美女视频黄免费的久久| 免费在线观看一区二区| 亚洲免费中文| 欧美成人免费视频| 久久久久久九九九九| 国产精品白丝av嫩草影院| 91久久精品一区二区三区| 欧美日本在线播放| 久久久蜜桃一区二区人| 国模私拍视频一区| 午夜一区二区三区在线观看| 亚洲国产专区| 麻豆国产精品777777在线| 日韩亚洲视频在线| 亚洲国产精品美女| 激情综合激情| 亚洲高清免费视频| 欧美日韩高清不卡| 久久不射2019中文字幕| 欧美自拍丝袜亚洲| 亚洲毛片在线观看| 亚洲欧美综合国产精品一区| 亚洲丶国产丶欧美一区二区三区| 亚洲国产综合视频在线观看| 国产精品久久久久9999吃药| 久久麻豆一区二区| 欧美日韩aaaaa| 另类专区欧美制服同性| 欧美日韩精品一区二区三区| 久久久噜噜噜久久狠狠50岁| 欧美日韩国产不卡在线看| 久久精品国产免费观看| 欧美精品一区视频| 你懂的一区二区| 国产精品系列在线播放| 亚洲黄网站黄| 在线日韩av永久免费观看| 亚洲无人区一区| 一二三四社区欧美黄| 久久婷婷av| 久久久久免费观看| 国产麻豆一精品一av一免费| 日韩午夜电影av| 亚洲高清一区二区三区| 久久激情视频久久| 欧美一区二区三区在线视频 | 国产精品成人播放| 欧美高清在线视频| 136国产福利精品导航网址| 亚洲主播在线| 亚洲影视在线播放| 欧美母乳在线| 亚洲人成网站在线观看播放| 在线观看欧美黄色| 久久av一区二区三区| 欧美一站二站| 国产亚洲欧美日韩一区二区| 午夜精品久久久久久久久久久久久| 亚洲一二区在线| 欧美视频不卡| 亚洲新中文字幕| 欧美一区二区三区四区夜夜大片 | 伊人久久婷婷| 久久精品国产成人| 久久免费国产| 国产亚洲欧美一级| 亚洲午夜电影网| 日韩视频免费观看高清在线视频| 亚洲欧美日韩国产一区二区三区| 亚洲人成网站色ww在线 | 久久免费黄色| 免费不卡中文字幕视频| 欧美日本国产视频| 葵司免费一区二区三区四区五区| 国产欧美日韩视频在线观看| 久久国产99| 久久综合狠狠综合久久综合88| 久久青青草综合| 亚洲国产精品久久久久秋霞不卡| 裸体歌舞表演一区二区| 免费视频一区| 亚洲国产欧美在线人成| 久久看片网站| 亚洲黄色天堂| 亚洲尤物精选| 国产一区二区三区黄视频| 久久手机免费观看| 一本久道久久综合婷婷鲸鱼| 午夜在线a亚洲v天堂网2018| 国产视频精品va久久久久久| 欧美在线网站| 亚洲国产精品一区| 亚洲一区日韩在线| 亚洲东热激情| 国产精品视频第一区| 久久免费高清视频| 99av国产精品欲麻豆| 久久九九全国免费精品观看| 亚洲精品黄色| 国产一区在线看| 欧美日韩xxxxx| 久久免费高清| 午夜电影亚洲| 亚洲人成网站精品片在线观看 | 国产精品久久久久久久久久妞妞 | 亚洲午夜影视影院在线观看| 久久性天堂网| 亚洲一区二区三区激情| 禁断一区二区三区在线| 欧美精品aa| 欧美在线播放一区二区| 日韩系列在线| 欧美黄色一级视频| 久久国产手机看片| 国产精品99久久不卡二区 | 日韩午夜电影在线观看| 国产亚洲精品美女| 国产精品国码视频| 欧美精品在欧美一区二区少妇| 久久精品国产亚洲精品 | 在线中文字幕不卡| 亚洲国产三级网|