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

asm, c, c++ are my all
-- Core In Computer
posts - 139,  comments - 123,  trackbacks - 0
線程同步是多線程程序設(shè)計的核心內(nèi)容,它的目的是正確處理多線程并發(fā)時的各種問題,例如線程的等待、多個線程訪問同一數(shù)據(jù)時的互斥,防死鎖等。Win32提供多種內(nèi)核對象和手段用于線程同步,如互斥量、信號量、事件、臨界區(qū)等。所不同的是,互斥量、信號量、事件都是Windows的內(nèi)核對象,當(dāng)程序?qū)@些對象進(jìn)行控制時會自動轉(zhuǎn)換到核心態(tài),而臨界區(qū)本身不是內(nèi)核對象,它是工作在用戶態(tài)的。我們知道從用戶態(tài)轉(zhuǎn)換到核心態(tài)是需要以時間為代價的,所以如果能在用戶態(tài)就簡單解決的問題,就可以不必勞煩核心態(tài)了。
這里我要說的是兩種用于C++的多線程同步類,通過對這兩種類的使用就可以方便的實現(xiàn)對變量或代碼段的加鎖控制,從而防止多線程對變量不正確的操作。
所謂加鎖,就是說當(dāng)我們要訪問某關(guān)鍵變量之前,都需要首先獲得允許才能繼續(xù),如果未獲得允許則只有等待。一個關(guān)鍵變量擁有一把鎖,一個線程必須先得到這把鎖(其實稱為鑰匙可能更形象)才可以訪問這個變量,而當(dāng)某個變量持有這把鎖的時候,其他線程就不能重復(fù)的得到它,只有等持有鎖的線程把鎖歸還以后其他線程才有可能得到它。之所以這樣做,就是為了防止一個線程讀取某對象途中另一線程對它進(jìn)行了修改,或兩線程同時對一變量進(jìn)行修改,例如:
// 全局:
??????? struct ?MyStruct? {? int ?a,?b;?} ;
???????MyStruct?s;
// 線程1:

??????? int ?a? = ?s.a;
???????
int ?b? =
?s.b;
// 線程2:

???????s.a ++ ;
???????s.b
-- ;
如果實際的執(zhí)行順序就是上述書寫的順序那到?jīng)]有什么,但如果線程2的執(zhí)行打斷了線程1,變?yōu)槿缦马樞颍?/font>
?????? int a = s.a;????? //線程1
?????? s.a++;??????????? //線程2
?????? s.b++;??????????? //線程2
?????? int b = s.b;????? //線程1
那么這時線程1讀出來的a和b就會有問題了,因為a是在修改前讀的,而b是在修改后讀的,這樣讀出來的是不完整的數(shù)據(jù),會對程序帶來不可預(yù)料的后果。天知道兩個程的調(diào)度順序是什么樣的。為了防止這種情況的出現(xiàn),需要對變量s加鎖,也就是當(dāng)線程1得到鎖以后就可以放心的訪問s,這時如果線程2要修改s,只有等線程1訪問完成以后將鎖釋放才可以,從而保證了上述兩線程交叉訪問變量的情況不會出現(xiàn)。
使用Win32提供的臨界區(qū)可以方便的實現(xiàn)這種鎖:
// 全局:
???????CRITICAL_SECTION?cs;
???????InitializeCriticalSection(
&
cs);
// 線程1:

???????EnterCriticalSection( & cs);
???????
int ?a? =
?s.a;
???????
int ?b? =
?s.b;
???????LeaveCriticalSection(
&
cs);
// 線程2:

???????EnterCriticalSection( & cs);
???????s.a
++
;
???????s.b
--
;
???????LeaveCriticalSection(
&
cs);
// 最后:

???????DeleteCriticalSection( & cs);
代碼中的臨界區(qū)變量(cs)就可以看作是變量s的鎖,當(dāng)函數(shù)EnterCriticalSection返回時,當(dāng)前線程就獲得了這把鎖,之后就是對變量的訪問了。訪問完成后,調(diào)用LeaveCriticalSection表示釋放這把鎖,允許其他線程繼續(xù)使用它。
如果每當(dāng)需要對一個變量進(jìn)行加鎖時都需要做這些操作,顯得有些麻煩,而且變量cs與s只有邏輯上的鎖關(guān)系,在語法上沒有什么聯(lián)系,這對于鎖的管理帶來了不小的麻煩。程序員總是最懶的,可以想出各種偷懶的辦法來解決問題,例如讓被鎖的變量與加鎖的變量形成物理上的聯(lián)系,使得鎖變量成為被鎖變量不可分割的一部分,這聽起來是個好主意。
首先想到的是把鎖封閉在一個類里,讓類的構(gòu)造函數(shù)和析構(gòu)函數(shù)來管理對鎖的初始化和鎖毀動作,我們稱這個鎖為“實例鎖”:
??????? class ?InstanceLockBase
???????
{
??????????????CRITICAL_SECTION?cs;
???????
protected
:
??????????????InstanceLockBase()?
{?InitialCriticalSection( & cs);?}

??????????????
~ InstanceLockBase()? {?DeleteCriticalSection( & cs);?}
???????}
;
如果熟悉C++,看到這里一定知道后面我要干什么了,對了,就是繼承,因為我把構(gòu)造函數(shù)和析構(gòu)函數(shù)都聲明為保護(hù)的(protected),這樣唯一的作用就是在子類里使用它。讓我們的被保護(hù)數(shù)據(jù)從這個類繼承,那么它們不就不可分割了嗎:
??????? struct ?MyStruct:? public ?InstanceLockBase
???????
{?…?} ;
什么?結(jié)構(gòu)體還能從類繼承?當(dāng)然,C++中結(jié)構(gòu)體和類除了成員的默認(rèn)訪問控制不同外沒有什么不一樣,class能做的struct也能做。此外,也許你還會問,如果被鎖的是個簡單類型,不能繼承怎么辦,那么要么用一個類對這個簡單類型進(jìn)行封裝(記得Java里有int和Integer嗎),要么只好手工管理它們的聯(lián)系了。如果被鎖類已經(jīng)有了基類呢?沒關(guān)系,C++是允許多繼承的,多一個基類也沒什么。
現(xiàn)在我們的數(shù)據(jù)里面已經(jīng)包含一把鎖了,之后就是要添加加鎖和解鎖的動作,把它們作為InstanceLockBase類的成員函數(shù)再合適不過了:
??????? class ?InstanceLockBase
???????
{
??????????????CRITICAL_SECTION?cs;
??????????????
void ?Lock()? {?EnterCriticalSection( & cs);?}

??????????????
void ?Unlock()? {?LeaveCriticalSection( & cs);?}
??????????????…
}
;
看到這里可能會發(fā)現(xiàn),我把Lock和Unlock函數(shù)都聲明為私有了,那么如何訪問這兩個函數(shù)呢?是的,我們總是需要有一個地方來調(diào)用這兩個函數(shù)以實現(xiàn)加鎖和解鎖的,而且它們總應(yīng)該成對出現(xiàn),但C++語法本身沒能限制我們必須成對的調(diào)用兩個函數(shù),如果加完鎖忘了解,那后果是嚴(yán)重的。這里有一個例外,就是C++對于構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用是自動成對的,對了,那就把對Lock和Unlock的調(diào)用專門寫在一個類的構(gòu)造函數(shù)和析構(gòu)函數(shù)中:
class ?InstanceLock
{
??????????????InstanceLockBase
*
?_pObj;
public
:
??????????????InstanceLock(InstanceLockBase
*
?pObj)
??????????????
{
?????????????????????_pObj?
= ?pObj;? // 這里會保存一份指向s的指針,用于解鎖

????????????????????? if (NULL? != ?_pObj)
????????????????????????????_pObj
-> Lock();?????? // 這里加鎖

??????????????}

??????????????
~ InstanceLock()
??????????????
{
?????????????????????
if (NULL? !=
?_pObj)
????????????????????????????_pObj
-> Unlock();??? // 這里解鎖

??????????????}

}
;
最后別忘了在類InstanceLockBase中把InstanceLock聲明為友元,使得它能正確訪問Lock和Unlock這兩個私有函數(shù):
class ?InstanceLockBase
{
??????????????friend?
class
?InstanceLock;
??????????????…
}
;
好了,有了上面的基礎(chǔ),現(xiàn)在對變量s的加解鎖管理變成了對InstanceLock的實例的生命周期的管理了。假如我們有一個函數(shù)ModifyS中要對s進(jìn)行修改,那么只要在函數(shù)一開始就聲明一個InstaceLock的實例,這樣整個函數(shù)就自動對s加鎖,一旦進(jìn)入這個函數(shù),其他線程就都不能獲得s的鎖了:
??????? void ?ModifyS()
???????
{
??????????????InstanceLock?
lock ( & s);???????? //
這里已經(jīng)實現(xiàn)加鎖了
??????????????
// some?operations?on?s

???????}
????
?????????????????????????????????????????? //
一旦離開lock對象的作用域,自動解鎖
如果是要對某函數(shù)中一部分代碼加鎖,只要用一對大括號把它們括起來再聲明一個lock就可以了:
???????…
???????
{
??????????????InstanceLock?
lock ( &
s);
??????????????
// ?do?something?…

???????}

???????…
好了,就是這么簡單。下面來看一個測試。
首先準(zhǔn)備一個輸出函數(shù),對我們理解程序有幫助。它會在輸出我們想輸出的內(nèi)容同時打出行號和時間:
void ?Say( char * ?text)
{
??????????????
static ? int ?count? = ? 0
;
??????????????SYSTEMTIME?st;
??????????????::GetLocalTime(
&
st);
??????????????printf(
" %03d?[%02d:%02d:%02d.%03d]%s " ,? ++
count,?st.wHour,?st.wMinute,?st.wSecond,?st.wMilliseconds,?text);
}
當(dāng)然,原則上當(dāng)多線程都調(diào)用這個函數(shù)時應(yīng)該對其靜態(tài)局部變量count進(jìn)行加鎖,這里就省略了。
我們聲明一個非常簡單的被鎖的類型,并生成一個實例:
class ?MyClass:? public ?InstanceLockBase
{}
;
MyClass?mc;
子線程的任務(wù)就是對這個對象加鎖,然后輸出一些信息:
DWORD?CALLBACK?ThreadProc(LPVOID?param)
{
??????????????InstanceLock?il(
&
mc);
??????????????Say(
" in?sub?thread,?lock "
);
??????????????Sleep(
2000
);
??????????????Say(
" in?sub?thread,?unlock "
);
??????????????
return ? 0
;
}
這里會輸出兩條信息,一是在剛剛獲得鎖的時間,二是在釋放鎖的時候,中間通過Sleep來延遲2秒。
主線程負(fù)責(zé)開啟子線程,然后也對mc加鎖:
CreateThread( 0 ,? 0 ,?ThreadProc,? 0 ,? 0 ,? 0 );
???????
{
??????????????InstanceLock?il(
&
mc);
??????????????Say(
" in?main?thread,?lock "
);
??????????????Sleep(
3000
);
??????????????Say(
" in?main?thread,?lock "
);
???????}
運行此程序,得到的輸出如下:
001 [13:43:23.781]in main thread, lock
002 [13:43:26.781]in main thread, lock
003 [13:43:26.781]in sub thread, lock
004 [13:43:28.781]in sub thread, unlock
從其輸出的行號和時間可以清楚的看到兩個線程間的互斥:當(dāng)主線程恰好首先獲得鎖時,它會延遲3秒,然后釋放鎖,之后子線程才得以繼續(xù)進(jìn)行。這個例子也證明我們的類工作的很好。
總結(jié)一下,要使用InstanceLock系列類,要做的就是:
1 讓被鎖類從InstanceLockBase繼承
2 所有要訪問被鎖對象的代碼前面聲明InstanceLock的實例,并傳入被鎖對象的指針。
?
附:完整源代碼:
#pragma ?once
#include?
< windows.h >
?
class ?InstanceLock;
?
class
?InstanceLockBase
{
???????friend?
class
?InstanceLock;
?
???????CRITICAL_SECTION?cs;
?
???????
void
?Lock()
???????
{
??????????????::EnterCriticalSection(
&
cs);
???????}

?
???????
void ?Unlock()
???????
{
??????????????::LeaveCriticalSection(
&
cs);
???????}

?
protected :
???????InstanceLockBase()
???????
{
??????????????::InitializeCriticalSection(
&
cs);
???????}

?
???????
~ InstanceLockBase()
???????
{
??????????????::DeleteCriticalSection(
&
cs);
???????}

}
;
?
class
?InstanceLock
{
???????InstanceLockBase
*
?_pObj;
public
:
???????InstanceLock(InstanceLockBase
*
?pObj)
???????
{
??????????????_pObj?
=
?pObj;
??????????????
if (NULL? !=
?_pObj)
?????????????????????_pObj
->
Lock();
???????}

?
???????
~ InstanceLock()
???????
{
??????????????
if (NULL? !=
?_pObj)
?????????????????????_pObj
->
Unlock();
???????}

}
;
posted on 2006-10-19 14:33 Jerry Cat 閱讀(1539) 評論(1)  編輯 收藏 引用

FeedBack:
# re: Win32環(huán)境下兩種用于C++的線程同步類(上)
2006-10-19 14:33 | Jerry Cat
不知here有沒有南京的網(wǎng)友, 我以前南京的一個同學(xué)趙小姐要我?guī)兔Πl(fā)個租房消息, 某雖不懂但老同學(xué)的事也不好推, 將就如下:

現(xiàn)有位于南京市江寧區(qū)"武夷花園"小區(qū)的三室一廳住房一套, 水,電,氣齊全, 室內(nèi)有熱水器, 電視機及床, 衣柜等簡單家具. 整租, 與人合租均可. 聯(lián)系人: 趙小姐 電話:025-83909202  回復(fù)  更多評論
  

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理



<2006年6月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

常用鏈接

留言簿(7)

隨筆檔案

最新隨筆

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
              亚洲第一色中文字幕| 久久久精品动漫| 国产欧美一区二区精品婷婷| 亚洲另类在线视频| 亚洲制服欧美中文字幕中文字幕| 国产日韩欧美自拍| 欧美日韩一区二区在线观看视频| 亚洲小说春色综合另类电影| 久久久久久国产精品mv| 亚洲国产精品国自产拍av秋霞| 免费91麻豆精品国产自产在线观看| 国产精品专区第二| 国产精品久久久一本精品| 欧美久久成人| 欧美日韩免费观看中文| 欧美日韩三级视频| 欧美日韩一区二区三区免费看| 免费试看一区| 男男成人高潮片免费网站| 久久麻豆一区二区| 欧美成人日本| 欧美精品aa| 欧美日韩免费一区| 国产精品羞羞答答xxdd| 国产亚洲精品aa午夜观看| 国产在线不卡精品| 女同一区二区| 国产美女诱惑一区二区| 亚洲第一天堂av| 国产精品99久久99久久久二8| 亚洲影视中文字幕| 免费久久99精品国产| 一区二区日韩| 蜜桃av久久久亚洲精品| 国产精品视频在线观看| 欧美一区二区三区精品| 欧美jizz19性欧美| 亚洲电影观看| 先锋影音久久| 亚洲精品欧美精品| 久久久精品一品道一区| 欧美日韩mp4| 91久久极品少妇xxxxⅹ软件| 欧美一级视频精品观看| 亚洲看片免费| 欧美视频在线视频| 国产一区二区丝袜高跟鞋图片| 黄网动漫久久久| 久久久久一区| 亚洲欧美国产精品专区久久| 欧美日韩午夜视频在线观看| 99视频有精品| 日韩一区二区久久| 欧美精品一区二区三区久久久竹菊 | 中文在线一区| 国产主播一区二区| 亚洲国产精品第一区二区| 久久av二区| 一区二区三区日韩| 欧美精品一区二区精品网| 在线欧美亚洲| 欧美电影免费观看高清完整版| 亚洲视频久久| 欧美系列精品| 亚洲免费视频观看| 亚洲午夜高清视频| 国产精品爱久久久久久久| 在线一区观看| 夜夜嗨av色综合久久久综合网| 欧美激情第3页| 亚洲乱亚洲高清| 亚洲精品免费一区二区三区| 亚洲六月丁香色婷婷综合久久| 国产精品入口福利| 香港久久久电影| 久久精品首页| 日韩一区二区高清| 久久久久.com| 亚洲女人天堂av| 免费日韩av| 久久精品午夜| 国产日韩欧美精品一区| 麻豆成人综合网| 国产自产在线视频一区| 男人的天堂亚洲| 亚洲免费婷婷| 亚洲国产高潮在线观看| 日韩一级成人av| 国产午夜精品全部视频播放| 美女999久久久精品视频| 欧美电影免费观看高清完整版| 亚洲第一区中文99精品| 99成人精品| 欧美国产视频一区二区| 亚洲精品视频免费| 亚洲视频久久| 国产精品毛片va一区二区三区| 亚洲永久免费观看| 欧美成人在线影院| 日韩一区二区高清| 欧美午夜剧场| 久久婷婷蜜乳一本欲蜜臀| 欧美成人免费全部观看天天性色| 亚洲国产一区二区三区在线播 | 午夜精品在线看| 国产精品九九| 免费国产自线拍一欧美视频| 日韩视频在线观看免费| 蜜臀91精品一区二区三区| 亚洲在线成人| 99精品视频一区| 国产自产2019最新不卡| 欧美日韩另类一区| 欧美阿v一级看视频| 久久精品导航| 西西裸体人体做爰大胆久久久| 久久av老司机精品网站导航| 亚洲精品乱码久久久久久日本蜜臀 | 久久国产一区| 亚洲天堂av在线免费观看| 国产精品久久久久久模特| 久久亚洲免费| 黄色成人在线网址| 欧美一区二区三区视频| 久久久久高清| 激情亚洲网站| 国产日韩精品一区| 国产精品久久久久久av福利软件| 欧美福利在线观看| 欧美激情综合亚洲一二区| 免费的成人av| 亚洲激情婷婷| 一级日韩一区在线观看| 9色精品在线| 欧美与欧洲交xxxx免费观看| 欧美在线电影| 另类亚洲自拍| 欧美精品九九| 国产一区二区久久精品| 国产日韩欧美综合一区| 在线精品在线| 午夜久久资源| 欧美激情国产高清| 亚洲欧美日韩在线观看a三区| 久久精品天堂| 欧美视频一区二区| 日韩视频在线你懂得| 欧美一区二区三区免费观看视频| 老牛嫩草一区二区三区日本| 亚洲最新合集| 欧美另类综合| 一本色道久久综合亚洲精品不| 久久久7777| 欧美一区免费视频| 国产欧美欧美| 久久精品一区二区国产| 午夜国产欧美理论在线播放| 亚洲高清一区二区三区| 中文国产一区| 久久亚洲精品中文字幕冲田杏梨 | 亚洲激情av在线| 性高湖久久久久久久久| 久久久久久成人| 国产精品一区二区三区免费观看| 伊人狠狠色j香婷婷综合| 亚洲天堂第二页| 欧美激情国产日韩| 久久乐国产精品| 国内精品久久久久国产盗摄免费观看完整版 | 久久九九精品| 国产精品久久久999| 亚洲特黄一级片| 99精品国产99久久久久久福利| 欧美 日韩 国产精品免费观看| 国产亚洲一区二区三区在线播放| 欧美高清视频在线| 亚洲国产福利在线| 欧美成人黑人xx视频免费观看| 久久久噜噜噜| 亚洲黄色在线观看| 亚洲欧洲偷拍精品| 欧美日韩精品二区第二页| 亚洲精品中文字幕有码专区| 欧美肥婆在线| 国产精品国产a| 欧美一区二区视频观看视频| 国产综合欧美在线看| 欧美不卡视频一区| 欧美日韩性视频在线| 午夜欧美理论片| 久久综合久久美利坚合众国| 日韩亚洲欧美综合| 欧美一级片一区| 亚洲精品久久在线| 亚洲欧美在线免费| 亚洲人线精品午夜| 午夜免费日韩视频| 欧美视频日韩视频| 亚洲免费中文字幕| 浪潮色综合久久天堂|