国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
c++多線程同步使用的對(duì)象
c++多線程同步使用的對(duì)象
線程的同步
Critical section(臨界區(qū))用來(lái)實(shí)現(xiàn)“排他性占有”。適用范圍是單一進(jìn)程的各線程之間。它是:
·         一個(gè)局部性對(duì)象,不是一個(gè)核心對(duì)象。
·         快速而有效率。
·         不能夠同時(shí)有一個(gè)以上的critical section被等待。
·         無(wú)法偵測(cè)是否已被某個(gè)線程放棄。
Mutex
Mutex是一個(gè)核心對(duì)象,可以在不同的線程之間實(shí)現(xiàn)“排他性占有”,甚至幾十那些現(xiàn)成分屬不同進(jìn)程。它是:
·         一個(gè)核心對(duì)象。
·         如果擁有mutex的那個(gè)線程結(jié)束,則會(huì)產(chǎn)生一個(gè)“abandoned”錯(cuò)誤信息。
·         可以使用Wait…()等待一個(gè)mutex。
·         可以具名,因此可以被其他進(jìn)程開(kāi)啟。
·         只能被擁有它的那個(gè)線程釋放(released)。
Semaphore
Semaphore被用來(lái)追蹤有限的資源。它是:
·         一個(gè)核心對(duì)象。
·         沒(méi)有擁有者。
·         可以具名,因此可以被其他進(jìn)程開(kāi)啟。
·         可以被任何一個(gè)線程釋放(released)。
Event Object
Event object通常使用于overlapped I/O,或用來(lái)設(shè)計(jì)某些自定義的同步對(duì)象。它是:
·         一個(gè)核心對(duì)象。
·         完全在程序掌控之下。
·         適用于設(shè)計(jì)新的同步對(duì)象。
·         “要求蘇醒”的請(qǐng)求并不會(huì)被儲(chǔ)存起來(lái),可能會(huì)遺失掉。
·         可以具名,因此可以被其他進(jìn)程開(kāi)啟。
Interlocked Variable
如果Interlocked…()函數(shù)被使用于所謂的spin-lock,那么他們只是一種同步機(jī)制。所謂spin-lock是一種busy loop,被預(yù)期在極短時(shí)間內(nèi)執(zhí)行,所以有最小的額外負(fù)擔(dān)(overhead)。系統(tǒng)核心偶爾會(huì)使用他們。除此之外,interlocked variables主要用于引用技術(shù)。他們:
·         允許對(duì)4字節(jié)的數(shù)值有些基本的同步操作,不需動(dòng)用到critical section或mutex之類(lèi)。
·         在SMP(Symmetric Multi-Processors)操作系統(tǒng)中亦可有效運(yùn)作。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
有關(guān)多線程的一些技術(shù)問(wèn)題:
1、   何時(shí)使用多線程?
2、   線程如何同步?
3、   線程之間如何通訊?
4、   進(jìn)程之間如何通訊?
先來(lái)回答第一個(gè)問(wèn)題,線程實(shí)際主要應(yīng)用于四個(gè)主要領(lǐng)域,當(dāng)然各個(gè)領(lǐng)域之間不是絕對(duì)孤立的,他們有可能是重疊的,但是每個(gè)程序應(yīng)該都可以歸于某個(gè)領(lǐng)域:
1、   offloading time-consuming task。由輔助線程來(lái)執(zhí)行耗時(shí)計(jì)算,而使GUI有更好的反應(yīng)。我想這應(yīng)該是我們考慮使用線程最多的一種情況吧。
2、   Scalability。服務(wù)器軟件最??紤]的問(wèn)題,在程序中產(chǎn)生多個(gè)線程,每個(gè)線程做一份小的工作,使每個(gè)CPU都忙碌,使CPU(一般是多個(gè))有最佳的使用率,達(dá)到負(fù)載的均衡,這比較復(fù)雜,我想以后再討論這個(gè)問(wèn)題。
3、   Fair-share resource allocation。當(dāng)你向一個(gè)負(fù)荷沉重的服務(wù)器發(fā)出請(qǐng)求,多少時(shí)間才能獲得服務(wù)。一個(gè)服務(wù)器不能同時(shí)為太多的請(qǐng)求服務(wù),必須有一個(gè)請(qǐng)求的最大個(gè)數(shù),而且有時(shí)候?qū)δ承┱?qǐng)求要優(yōu)先處理,這是線程優(yōu)先級(jí)干的活了。
4、   Simulations。線程用于仿真測(cè)試。
我把主要的目光放在第一個(gè)領(lǐng)域,因?yàn)樗俏蚁胍?。第二和第三個(gè)領(lǐng)域比較有意思,但是目前不在我的研究時(shí)間表中。
線程的同步機(jī)制:
1、   Event
用事件(Event)來(lái)同步線程是最具彈性的了。一個(gè)事件有兩種狀態(tài):激發(fā)狀態(tài)和未激發(fā)狀態(tài)。也稱(chēng)有信號(hào)狀態(tài)和無(wú)信號(hào)狀態(tài)。事件又分兩種類(lèi)型:手動(dòng)重置事件和自動(dòng)重置事件。手動(dòng)重置事件被設(shè)置為激發(fā)狀態(tài)后,會(huì)喚醒所有等待的線程,而且一直保持為激發(fā)狀態(tài),直到程序重新把它設(shè)置為未激發(fā)狀態(tài)。自動(dòng)重置事件被設(shè)置為激發(fā)狀態(tài)后,會(huì)喚醒“一個(gè)”等待中的線程,然后自動(dòng)恢復(fù)為未激發(fā)狀態(tài)。所以用自動(dòng)重置事件來(lái)同步兩個(gè)線程比較理想。MFC中對(duì)應(yīng)的類(lèi)為CEvent.。CEvent的構(gòu)造函數(shù)默認(rèn)創(chuàng)建一個(gè)自動(dòng)重置的事件,而且處于未激發(fā)狀態(tài)。共有三個(gè)函數(shù)來(lái)改變事件的狀態(tài):SetEvent,ResetEvent和PulseEvent。用事件來(lái)同步線程是一種比較理想的做法,但在實(shí)際的使用過(guò)程中要注意的是,對(duì)自動(dòng)重置事件調(diào)用SetEvent和PulseEvent有可能會(huì)引起死鎖,必須小心。
2、   Critical Section
使用臨界區(qū)域的第一個(gè)忠告就是不要長(zhǎng)時(shí)間鎖住一份資源。這里的長(zhǎng)時(shí)間是相對(duì)的,視不同程序而定。對(duì)一些控制軟件來(lái)說(shuō),可能是數(shù)毫秒,但是對(duì)另外一些程序來(lái)說(shuō),可以長(zhǎng)達(dá)數(shù)分鐘。但進(jìn)入臨界區(qū)后必須盡快地離開(kāi),釋放資源。如果不釋放的話,會(huì)如何?答案是不會(huì)怎樣。如果是主線程(GUI線程)要進(jìn)入一個(gè)沒(méi)有被釋放的臨界區(qū),呵呵,程序就會(huì)掛了!臨界區(qū)域的一個(gè)缺點(diǎn)就是:Critical Section不是一個(gè)核心對(duì)象,無(wú)法獲知進(jìn)入臨界區(qū)的線程是生是死,如果進(jìn)入臨界區(qū)的線程掛了,沒(méi)有釋放臨界資源,系統(tǒng)無(wú)法獲知,而且沒(méi)有辦法釋放該臨界資源。這個(gè)缺點(diǎn)在互斥器(Mutex)中得到了彌補(bǔ)。Critical Section在MFC中的相應(yīng)實(shí)現(xiàn)類(lèi)是CcriticalSection。CcriticalSection::Lock()進(jìn)入臨界區(qū),CcriticalSection::UnLock()離開(kāi)臨界區(qū)。
3、   Mutex
互斥器的功能和臨界區(qū)域很相似。區(qū)別是:Mutex所花費(fèi)的時(shí)間比Critical Section多的多,但是Mutex是核心對(duì)象(Event、Semaphore也是),可以跨進(jìn)程使用,而且等待一個(gè)被鎖住的Mutex可以設(shè)定TIMEOUT,不會(huì)像Critical Section那樣無(wú)法得知臨界區(qū)域的情況,而一直死等。MFC中的對(duì)應(yīng)類(lèi)為CMutex。Win32函數(shù)有:創(chuàng)建互斥體CreateMutex() ,打開(kāi)互斥體OpenMutex(),釋放互斥體ReleaseMutex()。Mutex的擁有權(quán)并非屬于那個(gè)產(chǎn)生它的線程,而是最后那個(gè)對(duì)此Mutex進(jìn)行等待操作(WaitForSingleObject等等)并且尚未進(jìn)行ReleaseMutex()操作的線程。線程擁有Mutex就好像進(jìn)入Critical Section一樣,一次只能有一個(gè)線程擁有該Mutex。如果一個(gè)擁有Mutex的線程在返回之前沒(méi)有調(diào)用ReleaseMutex(),那么這個(gè)Mutex就被舍棄了,但是當(dāng)其他線程等待(WaitForSingleObject等)這個(gè)Mutex時(shí),仍能返回,并得到一個(gè)WAIT_ABANDONED_0返回值。能夠知道一個(gè)Mutex被舍棄是Mutex特有的。
4、   Semaphore
信號(hào)量是最具歷史的同步機(jī)制。信號(hào)量是解決producer/consumer問(wèn)題的關(guān)鍵要素。對(duì)應(yīng)的MFC類(lèi)是Csemaphore。Win32函數(shù)CreateSemaphore()用來(lái)產(chǎn)生信號(hào)量。ReleaseSemaphore()用來(lái)解除鎖定。Semaphore的現(xiàn)值代表的意義是目前可用的資源數(shù),如果Semaphore的現(xiàn)值為1,表示還有一個(gè)鎖定動(dòng)作可以成功。如果現(xiàn)值為5,就表示還有五個(gè)鎖定動(dòng)作可以成功。當(dāng)調(diào)用Wait…等函數(shù)要求鎖定,如果Semaphore現(xiàn)值不為0,Wait…馬上返回,資源數(shù)減1。當(dāng)調(diào)用ReleaseSemaphore()資源數(shù)加1,當(dāng)時(shí)不會(huì)超過(guò)初始設(shè)定的資源總數(shù)。
線程之間的通訊:
線程常常要將數(shù)據(jù)傳遞給另外一個(gè)線程。Worker線程可能需要告訴別人說(shuō)它的工作完成了,GUI線程則可能需要交給Worker線程一件新的工作。
通過(guò)PostThreadMessage(),可以將消息傳遞給目標(biāo)線程,當(dāng)然目標(biāo)線程必須有消息隊(duì)列。以消息當(dāng)作通訊方式,比起標(biāo)準(zhǔn)技術(shù)如使用全局變量等,有很大的好處。如果對(duì)象是同一進(jìn)程中的線程,可以發(fā)送自定義消息,傳遞數(shù)據(jù)給目標(biāo)線程,如果是線程在不同的進(jìn)程中,就涉及進(jìn)程之間的通訊了。下面將會(huì)講到。
進(jìn)程之間的通訊:
當(dāng)線程分屬于不同進(jìn)程,也就是分駐在不同的地址空間時(shí),它們之間的通訊需要跨越地址空間的邊界,便得采取一些與同一進(jìn)程中不同線程間通訊不同的方法。
1、   Windows專(zhuān)門(mén)定義了一個(gè)消息:WM_COPYDATA,用來(lái)在線程之間搬移數(shù)據(jù),――不管兩個(gè)線程是否同屬于一個(gè)進(jìn)程。同時(shí)接受這個(gè)消息的線程必須有一個(gè)窗口,即必須是UI線程。WM_COPYDATA必須由SendMessage()來(lái)發(fā)送,不能由PostMessage()等來(lái)發(fā)送,這是由待發(fā)送數(shù)據(jù)緩沖區(qū)的生命期決定的,出于安全的需要。
2、   WM_COPYDATA效率上面不是太高,如果要求高效率,可以考慮使用共享內(nèi)存(Shared Memory)。使用共享內(nèi)存要做的是:設(shè)定一塊內(nèi)存共享區(qū)域;使用共享內(nèi)存;同步處理共享內(nèi)存。
第一步:設(shè)定一塊內(nèi)存共享區(qū)域。首先,CreateFileMapping()產(chǎn)生一個(gè)file-mapping核心對(duì)象,并指定共享區(qū)域的大小。MapViewOfFile()獲得一個(gè)指針指向可用的內(nèi)存。如果是C/S模式,由Server端來(lái)產(chǎn)生file-mapping,那么Client端使用OpenFileMapping(),然后調(diào)用MapViewOfFile()。
第二步:使用共享內(nèi)存。共享內(nèi)存指針的使用是一件比較麻煩的事,我們需要借助_based屬性,允許指針被定義為從某一點(diǎn)開(kāi)始起算的32位偏移值。
第三步:清理。UnmapViewOfFile()交出由MapViewOfFile()獲得的指針,CloseHandle()交出file-mapping核心對(duì)象的handle。
第四步:同步處理??梢越柚鶰utex來(lái)進(jìn)行同步處理。
雖然多線程能給我們帶來(lái)好處,但是也有不少問(wèn)題需要解決。例如,對(duì)于像磁盤(pán)驅(qū)動(dòng)器這樣獨(dú)占性系統(tǒng)資源,由于線程可以執(zhí)行進(jìn)程的任何代碼段,且線程的運(yùn)行是由系統(tǒng)調(diào)度自動(dòng)完成的,具有一定的不確定性,因此就有可能出現(xiàn)兩個(gè)線程同時(shí)對(duì)磁盤(pán)驅(qū)動(dòng)器進(jìn)行操作,從而出現(xiàn)操作錯(cuò)誤;又例如,對(duì)于銀行系統(tǒng)的計(jì)算機(jī)來(lái)說(shuō),可能使用一個(gè)線程來(lái)更新其用戶(hù)數(shù)據(jù)庫(kù),而用另外一個(gè)線程來(lái)讀取數(shù)據(jù)庫(kù)以響應(yīng)儲(chǔ)戶(hù)的需要,極有可能讀數(shù)據(jù)庫(kù)的線程讀取的是未完全更新的數(shù)據(jù)庫(kù),因?yàn)榭赡茉谧x的時(shí)候只有一部分?jǐn)?shù)據(jù)被更新過(guò)。
使隸屬于同一進(jìn)程的各線程協(xié)調(diào)一致地工作稱(chēng)為線程的同步。MFC提供了多種同步對(duì)象,下面我們只介紹最常用的四種:
臨界區(qū)(CCriticalSection)
事件(CEvent)
互斥量(CMutex)
信號(hào)量(CSemaphore)
通過(guò)這些類(lèi),我們可以比較容易地做到線程同步。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
進(jìn)/線程間同步 通訊的方法
Windows線程同步與互斥技術(shù)總結(jié)
自考本科計(jì)算機(jī)網(wǎng)絡(luò)工程第四章
delphi TThread對(duì)象
臨界區(qū)
C++多線程的幾點(diǎn)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服