www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 芯聞號 > 充電吧
[導讀]l??????? 窗口置頂::SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | WS_EX_TOPMOST);l?

l??????? 窗口置頂

::SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | WS_EX_TOPMOST);

l??????? 取消置頂

::SetWindowPos(GetSafeHwnd(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

?

l??????? 寫入配置文件。

::WritePrivateProfileString("Settings","AlwaysOnTop",m_bAlwaysOnTop? "1":"0",".\Settings.ini");


l??????? 讀取配置文件

::GetPrivateProfileInt("Selections","m_bAddNew",0,".\Settings.ini")

?

l??????? 數(shù)據(jù)綁定

DDX_Check(pDX, IDC_CHECK1_ADDNEW, m_bAddNew);

?

//讀寫INI/ini文件*************************************************?

//寫入值字段名變量名值帶目錄文件名?
WritePrivateProfileString("目錄","path",cs, regpath);?
//寫入結(jié)構(gòu)體字段名變量名值大小帶目錄文件名?
WritePrivateProfileStruct("字體","font",&LF,sizeof(LOGFONT),regpath);//結(jié)構(gòu)體?
//讀入字符字段名變量名默認值字符緩沖區(qū)長度帶目錄文件名?
GetPrivateProfileString("目錄","path","", buffer.GetBuffer(260),260,regpath);?
//讀入整數(shù)值字段名變量名默認值帶目錄文件名?
GetPrivateProfileInt("colors","red",255, regpath);?
//讀入結(jié)構(gòu)體字段名變量名值大小帶目錄文件名?
GetPrivateProfileStruct("字體","font",&LF,sizeof(LOGFONT),regpath);?

線程

進程是資源分配的基本單位。所有與該進程有關(guān)的資源,都被記錄在進程控制塊PCB中。以表示該進程擁有這些資源或正在使用它們?! ?/p>

另外,進程也是搶占處理機的調(diào)度單位,它擁有一個完整的虛擬地址空間。   

與進程相對應,線程與資源分配無關(guān),它屬于某一個進程,并與進程內(nèi)的其他線程一起共享進程的資源?! ?/p>

當進程發(fā)生調(diào)度時,不同的進程擁有不同的虛擬地址空間,而同一進程內(nèi)的不同線程共享同一地址空間。   

線程只由相關(guān)堆棧(系統(tǒng)?;蛴脩魲#┘拇嫫骱途€程控制表TCB組成。寄存器可被用來存儲線程內(nèi)的局部變量,但不能存儲其他線程的相關(guān)變量?! ?/p>

發(fā)生進程切換與發(fā)生線程切換時相比較,進程切換時涉及到有關(guān)資源指針的保存以及地址空間的變化等問題;線程切換時,由于同進程內(nèi)的線程共享資源和地址空間,將不涉及資源信息的保存和地址變化問題,從而減少了操作系統(tǒng)的開銷時間。而且,進程的調(diào)度與切換都是由操作系統(tǒng)內(nèi)核完成,而線程則既可由操作系統(tǒng)內(nèi) 核完成,也可由用戶程序進行。

因為進程內(nèi)的線程分享相同的資源,所以需要在系統(tǒng)級別上設(shè)置控制機制來保證數(shù)據(jù)的完整性。當一個線程修改了某個變量,而另一個線程試圖讀取它時,或者兩個線程同時修改同一變量,就會影響到數(shù)據(jù)的完整性,為防止這個問題,操作系統(tǒng)提供了一種相互排斥對象,簡寫為mutex。在多線程程序中,mutex是通過編程來實現(xiàn)的,可防止多個線程在同一時間訪問同一資源。??? 當一個線程需要訪問某一資源時,它必須先請求一個mutex,一旦線程得到一個mutex,其他想獲取同一mutex的線程被阻塞,并處于低CPU占用的等待狀態(tài);一旦這個線程完成了數(shù)據(jù)訪問,它會釋放對應的mutex,這就允許其他線程獲取以訪問相關(guān)的數(shù)據(jù)。

線程,有時被稱為輕量級進程(Lightweight Process,LWP),是程序執(zhí)行流的最小單元。一個標準的線程由線程ID,當前指令指針(PC),寄存器集合和堆棧組成。另外,線程是進程中的一個實體,是被系統(tǒng)獨立調(diào)度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。一個線程可以創(chuàng)建和撤消另一個線程,同一進程中的多個線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約,致使線程在運行中呈現(xiàn)出間斷性。線程也有就緒、阻塞和運行三種基本狀態(tài)。每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。

線程是程序中一個單一的順序控制流程。在單個程序中同時運行多個線程完成不同的工作,稱為多線程。???

每個線程中都應具有一個用于控制線程運行的線程控制塊TCB,用于指示被執(zhí)行指令序列的程序計數(shù)器、保留局部變量、少數(shù)狀態(tài)參數(shù)和返回地址等的一組寄存器和堆棧。

1.輕型實體   

線程中的實體基本上不擁有系統(tǒng)資源,只是有一點必不可少的、能保證獨立運行的資源,比如,在每個線程中都應具有一個用于控制線程運行的線程控制塊TCB,用于指示被執(zhí)行指令序列的程序計數(shù)器、保留局部變量、少數(shù)狀態(tài)參數(shù)和返回地址等的一組寄存器和堆棧。   

2.獨立調(diào)度和分派的基本單位。   

在多線程OS中,線程是能獨立運行的基本單位,因而也是獨立調(diào)度和分派的基本單位。由于線程很“輕”,故線程的切換非常迅速且開銷小。   

3.可并發(fā)執(zhí)行。   

在一個進程中的多個線程之間,可以并發(fā)執(zhí)行,甚至允許在一個進程中所有線程都能并發(fā)執(zhí)行;同樣,不同進程中的線程也能并發(fā)執(zhí)行。  

4.共享進程資源。   

在同一進程中的各個線程,都可以共享該進程所擁有的資源,這首先表現(xiàn)在:所有線程都具有相同的地址空間(進程的地址空間),這意味著,線程可以訪問該地址空間的每一個虛地址;此外,還可以訪問進程所擁有的已打開文件、定時器、信號量機構(gòu)等。

  

線程與進程的區(qū)別可以歸納為以下幾點:   

l???????? 地址空間和其它資源(如打開文件):進程間相互獨立,同一進程的各線程間共享。某進程內(nèi)的線程在其它進程不可見?! ?/p>

l???????? 通信:進程間通信IPC,線程間可以直接讀寫進程數(shù)據(jù)段(如全局變量)來進行通信——需要進程同步和互斥手段的輔助,以保證數(shù)據(jù)的一致性。   

l???????? 調(diào)度和切換:線程上下文切換比進程上下文切換要快得多。  

l???????? 在多線程OS中,進程不是一個可執(zhí)行的實體。

?

線程的生命狀態(tài)與周期

1.新建 2.就緒 3.運行 4.阻塞 5.死亡

線程有兩個基本類型:

  用戶級線程:管理過程全部由用戶程序完成,操作系統(tǒng)內(nèi)核心只對進程進行管理。

系統(tǒng)級線程(核心級線程):由操作系統(tǒng)內(nèi)核進行管理。操作系統(tǒng)內(nèi)核給應用程序提供相應的系統(tǒng)調(diào)用和應用程序接口API,以使用戶程序可以創(chuàng)建、執(zhí)行、撤消線程。

?

?

函數(shù)

操作系統(tǒng)

描述

使用的類

CreateThread

Windows

創(chuàng)建一個Windows線程

CThread

WaitForSingleObject

Windows

等待一個對象有信號

CThread, CMutex, CEvent

CreateMutex

Windows

創(chuàng)建一個命名或未命名的mutex

CMutex

CloseHandle

Windows

關(guān)閉某一Windows句柄以釋放資源

CMutex, CEvent, CThread

ReleaseMutex

Windows

釋放某一之前獲取,并由WaitForSingleObject鎖定的mutex

CMutex CEvent

CreateEvent

Windows

創(chuàng)建一個Windows事件對象

CEvent

SetEvent

Windows

設(shè)置某一Windows事件對象為有信號狀態(tài)

CEvent

?

?

CMutex類的函數(shù)

函數(shù)

描述

void CMutex()

構(gòu)造函數(shù)

void Lock()

鎖定mutex對象或當它阻塞時等待

void Unlock()

解鎖之前阻塞的mutex

?

2、DWORD SuspendThread(HANDLE hThread);

該函數(shù)用于掛起指定的線程,如果函數(shù)執(zhí)行成功,則線程的執(zhí)行被終止。 3、DWORD

3、ResumeThread(HANDLE hThread);

該函數(shù)用于結(jié)束線程的掛起狀態(tài),執(zhí)行線程。

4、VOID ExitThread(DWORD dwExitCode);

該函數(shù)用于線程終結(jié)自身的執(zhí)行,主要在線程的執(zhí)行函數(shù)中被調(diào)用。其中參數(shù)dwExitCode用來設(shè)置線程的退出碼。

5、BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);

  一般情況下,線程運行結(jié)束之后,線程函數(shù)正常返回,但是應用程序可以調(diào)用TerminateThread強行終止某一線程的執(zhí)行。各參數(shù)含義如下:

hThread:將被終結(jié)的線程的句柄;

dwExitCode:用于指定線程的退出碼。

  使用TerminateThread()終止某個線程的執(zhí)行是不安全的,可能會引起系統(tǒng)不穩(wěn)定;雖然該函數(shù)立即終止線程的執(zhí)行,但并不釋放線程所占用的資源。因此,一般不建議使用該函數(shù)。

6、BOOL PostThreadMessage(DWORD idThread,

??????????? UINT Msg,

??????????? WPARAM wParam,

??????????? LPARAM lParam);

?

l???????? 該函數(shù)將一條消息放入到指定線程的消息隊列中,并且不等到消息被該線程處理時便返回。

l???????? idThread:將接收消息的線程的ID;

l???????? Msg:指定用來發(fā)送的消息;

l???????? wParam:同消息有關(guān)的字參數(shù);

l???????? lParam:同消息有關(guān)的長參數(shù);

l???????? 調(diào)用該函數(shù)時,如果即將接收消息的線程沒有創(chuàng)建消息循環(huán),則該函數(shù)執(zhí)行失敗。

volatile修飾符的作用是告訴編譯器無需對該變量作任何的優(yōu)化,即無需將它放到一個寄存器中,并且該值可被外部改變。對于多線程引用的全局變量來說,volatile 是一個非常重要的修飾符。

?

終止線程

WaitForSingleObject函數(shù),其函數(shù)原型為:DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);

?

hHandle為要監(jiān)視的對象(一般為同步對象,也可以是線程)的句柄;

dwMilliseconds為hHandle對象所設(shè)置的超時值,單位為毫秒;

  當在某一線程中調(diào)用該函數(shù)時,線程暫時掛起,系統(tǒng)監(jiān)視hHandle所指向的對象的狀態(tài)。如果在掛起的dwMilliseconds毫秒內(nèi),線程所等待的對象變?yōu)橛行盘枲顟B(tài),則該函數(shù)立即返回;如果超時時間已經(jīng)到達dwMilliseconds毫秒,但hHandle所指向的對象還沒有變成有信號狀態(tài),函數(shù)照樣返回。參數(shù)dwMilliseconds有兩個具有特殊意義的值:0和INFINITE。若為0,則該函數(shù)立即返回;若為INFINITE,則線程一直被掛起,直到hHandle所指向的對象變?yōu)橛行盘枲顟B(tài)時為止。

  本例程調(diào)用該函數(shù)的作用是按下IDC_START按鈕后,一直等到線程返回,再恢復IDC_START按鈕正常狀態(tài)。編譯運行該例程并細心體會。

::TerminateThread(m_hThread, 0 );

m_hThread = NULL;

?

HANDLE m_hThread;//線程

DWORD m_hThreadId;? //線程ID

? static DWORD WINAPI ThreadProc( LPVOID lParam ) //線程函數(shù),非類成員

{

??? CString str;

??? str.Format(L"%d",AfxGetApp()->m_nThreadID);

//AfxGetApp()獲取當前運行的程序?qū)ο笾羔楥heheDlg*

??? ((CheheDlg*)lParam)->SetDlgItemText(IDC_EDIT1,str);//轉(zhuǎn)換對象指針

??? return 1;

}

//如果未傳遞當前運行的句柄。

??? CListBox *list;

??? list=(CListBox*)AfxGetApp()->GetMainWnd()->GetDlgItem(IDC_LIST1);

??? list->AddString(str);

AfxGetApp()獲取了該應用程序的實例句柄

GetMainWnd()獲取了該應用程序的主窗口

?

??? m_hThread=::CreateThread(NULL,0,ThreadProc,this,0,&m_hThreadId);//this當前對象指針

?

線程的創(chuàng)建

使用CreateThread函數(shù)創(chuàng)建線程,CreateThread的原型如下:

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes,

DWORD dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreationFlags, // creation flags

LPDWORD lpThreadId

);

其中:

l???????? lpThreadAttributes表示創(chuàng)建線程的安全屬性,NT下有用。

l???????? dwStackSize指定線程棧的尺寸,如果為0則與進程主線程棧相同。

l???????? lpStartAddress指定線程開始運行的地址。

l???????? lpParameter表示傳遞給線程的32位的參數(shù)。

l???????? dwCreateFlages表示是否創(chuàng)建后掛起線程(取值CREATE_SUSPENDED),掛起后調(diào)用ResumeThread繼續(xù)執(zhí)行。

l???????? lpThreadId用來存放返回的線程ID。

?

??? h=CreateThread(NULL,NULL,ThreadProc,this,CREATE_SUSPENDED,NULL);//創(chuàng)建后掛起線程

ResumeThread(h);//恢復線程

SuspendThread(h);//掛起線程

?

static DWORD WINAPI ThreadProc( LPVOID lParam )

{

??? CString str;

??? CTime c;

??? while(1)

??? {

??????? c=CTime::GetCurrentTime();

??????? str=c.Format("%H:%M:%S");

??? ((CheheDlg*)lParam)->SetDlgItemText(IDC_EDIT1,str);

??? }

??????? return 0;

}

??

//獲取當前線程的優(yōu)先級

??????? DWORD dw= GetThreadPriority(GetCurrentThread());

??????? str.Format(L"%x",dw);

?

//設(shè)置線程優(yōu)先級:1:線程句柄? 2:優(yōu)先級THREAD_PRIORITY_NORMAL??? 0

BOOL WINAPI SetThreadPriority(

? __in????????? HANDLE hThread,

? __in????????? int nPriority

);

?

線程的終止

以下情況終止一個線程:

l???????? 調(diào)用了ExitThread函數(shù);

l???????? 線程函數(shù)返回:主線程返回導致ExitProcess被調(diào)用,其他線程返回導致ExitThread被調(diào)用;

l???????? 調(diào)用ExitProcess導致進程的所有線程終止;

l???????? 調(diào)用TerminateThread終止一個線程;

l???????? 調(diào)用TerminateProcess終止一個進程時,導致其所有線程的終止。

l???????? 當用TerminateProcess或者TerminateThread終止進程或線程時,DLL的入口函數(shù)DllMain不會被執(zhí)行(如果有DLL的話)。

?

線程同步

同步可以保證在一個時間內(nèi)只有一個線程對某個資源(如操作系統(tǒng)資源等共享資源)有控制權(quán)。共享資源包括全局變量、公共數(shù)據(jù)成員或者句柄等。同步還可以使得有關(guān)聯(lián)交互作用的代碼按一定的順序執(zhí)行。

同步對象有:Critical_section(關(guān)鍵段),Event(事件),Mutex(互斥對象),Semaphores(信號量)。

?

在Win32 API的基礎(chǔ)之上,MFC提供了處理線程的類和函數(shù)。處理線程的類是CWinThread,函數(shù)是AfxBeginThread、AfxEndThread等。

CWinThread是MFC線程類,它的成員變量m_hThread和m_hThreadID是對應的Win32線程句柄和線程ID。

MFC明確區(qū)分兩種線程:用戶界面線程(User interface thread)和工作者線程(Worker thread)。用戶界面線程一般用于處理用戶輸入并對用戶產(chǎn)生的事件和消息作出應答。工作者線程用于完成不要求用戶輸入的任務(wù),如耗時計算。

Win32 API并不區(qū)分線程類型,它只需要知道線程的開始地址以便它開始執(zhí)行線程。MFC為用戶界面線程特別地提供消息泵來處理用戶界面的事件。CWinApp對象是用戶界面線程對象的一個例子,CWinApp從類CWinThread派生并處理用戶產(chǎn)生的事件和消息。

?

 為了防止用戶定義的消息ID與系統(tǒng)的消息ID沖突,MS(Microsoft)定義了一個宏WM_USER,小于WM_USER的ID被系統(tǒng)使用,大于WM_USER的ID被用戶使用。

?

PostMessage是Windows API(應用程序接口) 中的一個常用函數(shù),用于將一條消息放入到消息隊列中。該函數(shù)將一個消息放入(寄送)到與指定窗口創(chuàng)建的線程相聯(lián)系消息隊列里,不等待線程處理消息就返回,是異步消息模式。消息隊列里的消息通過調(diào)用GetMessage和PeekMessage取得。函數(shù)原型:B00L PostMessage(HWNDhWnd,UINTMsg,WPARAMwParam,LPARAMlParam);   

參數(shù)說明:  

hWnd:其窗口程序接收消息的窗口的句柄??扇∮刑囟êx的兩個值:   

HWND_BROADCAST:消息被寄送到系統(tǒng)的所有頂層窗口,包括無效或不可見的非自身擁有窗口、 被覆蓋的窗口和彈出式窗口。消息不被寄送到子窗口  

NULL:此函數(shù)的操作和調(diào)用參數(shù)dwThread設(shè)置為當前線程的標識符PostThreadMessage函數(shù)一樣   

Msg:指定被寄送的消息。   

wParam:指定附加的消息特定的信息。   

IParam:指定附加的消息特定的信息。   

返回值:如果函數(shù)調(diào)用成功,返回非零值:如果函數(shù)調(diào)用失敗,返回值是零。若想獲得更多的錯誤信息,請調(diào)用GetLastError函數(shù)。

?

使隸屬于同一進程的各線程協(xié)調(diào)一致地工作稱為線程同步

?

使用 CCriticalSection 類

  當多個線程訪問一個獨占性共享資源時,可以使用“臨界區(qū)”對象。任一時刻只有一個線程可以擁有臨界區(qū)對象,擁有臨界區(qū)的線程可以訪問被保護起來的資源或代碼段,其他希望進入臨界區(qū)的線程將被掛起等待,直到擁有臨界區(qū)的線程放棄臨界區(qū)時為止,這樣就保證了不會在同一時刻出現(xiàn)多個線程訪問共享資源。

?

CCriticalSection類的用法非常簡單,步驟如下:

定義CCriticalSection類的一個全局對象(以使各個線程均能訪問),如CCriticalSection critical_section;

在訪問需要保護的資源或代碼之前,調(diào)用CCriticalSection類的成員Lock()獲得臨界區(qū)對象: critical_section.Lock();

?

在線程中調(diào)用該函數(shù)來使線程獲得它所請求的臨界區(qū)。如果此時沒有其它線程占有臨界區(qū)對象,則調(diào)用Lock()的線程獲得臨界區(qū);否則,線程將被掛起,并放入到一個系統(tǒng)隊列中等待,直到當前擁有臨界區(qū)的線程釋放了臨界區(qū)時為止。

訪問臨界區(qū)完畢后,使用CCriticalSection的成員函數(shù)Unlock()來釋放臨界區(qū):critical_section.Unlock();

?

再通俗一點講,就是線程A執(zhí)行到critical_section.Lock();語句時,如果其它線程(B)正在執(zhí)行critical_section.Lock();語句后且critical_section. Unlock();語句前的語句時,線程A就會等待,直到線程B執(zhí)行完critical_section. Unlock();語句,線程A才會繼續(xù)執(zhí)行。

B、使用 CEvent 類

  CEvent 類提供了對事件的支持。事件是一個允許一個線程在某種情況發(fā)生時,喚醒另外一個線程的同步對象。例如在某些網(wǎng)絡(luò)應用程序中,一個線程(記為A)負責監(jiān)聽通訊端口,另外一個線程(記為B)負責更新用戶數(shù)據(jù)。通過使用CEvent 類,線程A可以通知線程B何時更新用戶數(shù)據(jù)。每一個CEvent 對象可以有兩種狀態(tài):有信號狀態(tài)和無信號狀態(tài)。線程監(jiān)視位于其中的CEvent 類對象的狀態(tài),并在相應的時候采取相應的操作。

  在MFC中,CEvent 類對象有兩種類型:人工事件和自動事件。一個自動CEvent 對象在被至少一個線程釋放后會自動返回到無信號狀態(tài);而人工事件對象獲得信號后,釋放可利用線程,但直到調(diào)用成員函數(shù)ReSetEvent()才將其設(shè)置為無信號狀態(tài)。在創(chuàng)建CEvent 類的對象時,默認創(chuàng)建的是自動事件。 CEvent 類的各成員函數(shù)的原型和參數(shù)說明如下:

?

1、CEvent(BOOL bInitiallyOwn=FALSE,

????????? BOOL bManualReset=FALSE,

????????? LPCTSTR lpszName=NULL,

????????? LPSECURITY_ATTRIBUTES lpsaAttribute=NULL);

bInitiallyOwn:指定事件對象初始化狀態(tài),TRUE為有信號,F(xiàn)ALSE為無信號;

bManualReset:指定要創(chuàng)建的事件是屬于人工事件還是自動事件。TRUE為人工事件,F(xiàn)ALSE為自動事件;

后兩個參數(shù)一般設(shè)為NULL,在此不作過多說明。

?

2、BOOL CEvent::SetEvent();

  將 CEvent 類對象的狀態(tài)設(shè)置為有信號狀態(tài)。如果事件是人工事件,則 CEvent 類對象保持為有信號狀態(tài),直到調(diào)用成員函數(shù)ResetEvent()將 其重新設(shè)為無信號狀態(tài)時為止。如果CEvent 類對象為自動事件,則在SetEvent()將事件設(shè)置為有信號狀態(tài)后,CEvent 類對象由系統(tǒng)自動重置為無信號狀態(tài)。

如果該函數(shù)執(zhí)行成功,則返回非零值,否則返回零。 3、BOOL CEvent::ResetEvent();

  該函數(shù)將事件的狀態(tài)設(shè)置為無信號狀態(tài),并保持該狀態(tài)直至SetEvent()被調(diào)用時為止。由于自動事件是由系統(tǒng)自動重置,故自動事件不需要調(diào)用該函數(shù)。如果該函數(shù)執(zhí)行成功,返回非零值,否則返回零。我們一般通過調(diào)用WaitForSingleObject函數(shù)來監(jiān)視事件狀態(tài)。前面我們已經(jīng)介紹了該函數(shù)。由于語言描述的原因,CEvent 類的理解確實有些難度,但您只要通過仔細玩味下面例程,多看幾遍就可理解。

例程9 MultiThread9

?

CEvent eventWriteD;

線程WriteD執(zhí)行到 WaitForSingleObject(eventWriteD.m_hObject,INFINITE);處等待,直到事件eventWriteD為有信號該線程才往下執(zhí)行,因為eventWriteD對象是自動事件,則當WaitForSingleObject()返回時,系統(tǒng)自動把eventWriteD對象重置為無信號狀態(tài)

??? CWinThread *pWriteD=AfxBeginThread(WriteD,

??????? &m_ctrlD,

??????? THREAD_PRIORITY_NORMAL,

??????? 0,

??????? CREATE_SUSPENDED);

??? pWriteD->ResumeThread();

?

C、使用CMutex 類

互斥對象與臨界區(qū)對象很像.互斥對象與臨界區(qū)對象的不同在于:互斥對象可以在進程間使用,而臨界區(qū)對象只能在同一進程的各線程間使用。當然,互斥對象也可以用于同一進程的各個線程間,但是在這種情況下,使用臨界區(qū)會更節(jié)省系統(tǒng)資源,更有效率。

?

D、使用CSemaphore 類? afxmt.h

  當需要一個計數(shù)器來限制可以使用某個線程的數(shù)目時,可以使用“信號量”對象。CSemaphore 類的對象保存了對當前訪問某一指定資源的線程的計數(shù)值,該計數(shù)值是當前還可以使用該資源的線程的數(shù)目。如果這個計數(shù)達到了零,則所有對這個CSemaphore 類對象所控制的資源的訪問嘗試都被放入到一個隊列中等待,直到超時或計數(shù)值不為零時為止。一個線程被釋放已訪問了被保護的資源時,計數(shù)值減1;一個線程完成了對被控共享資源的訪問時,計數(shù)值增1。這個被CSemaphore 類對象所控制的資源可以同時接受訪問的最大線程數(shù)在該對象的構(gòu)建函數(shù)中指定。

?

CSemaphore 類的構(gòu)造函數(shù)原型及參數(shù)說明如下:

?

CSemaphore (LONG lInitialCount=1,

??????????? LONG lMaxCount=1,

??????????? LPCTSTR pstrName=NULL,

??????????? LPSECURITY_ATTRIBUTES lpsaAttributes=NULL);

lInitialCount:信號量對象的初始計數(shù)值,即可訪問線程數(shù)目的初始值;

lMaxCount:信號量對象計數(shù)值的最大值,該參數(shù)決定了同一時刻可訪問由信號量保護的資源的線程最大數(shù)目;

后兩個參數(shù)在同一進程中使用一般為NULL,不作過多討論;

  在用CSemaphore 類的構(gòu)造函數(shù)創(chuàng)建信號量對象時要同時指出允許的最大資源計數(shù)和當前可用資源計數(shù)。一般是將當前可用資源計數(shù)設(shè)置為最大資源計數(shù),每增加一個線程對共享資源的訪問,當前可用資源計數(shù)就會減1,只要當前可用資源計數(shù)是大于0的,就可以發(fā)出信號量信號。但是當前可用計數(shù)減小到0時,則說明當前占用資源的線程數(shù)已經(jīng)達到了所允許的最大數(shù)目,不能再允許其它線程的進入,此時的信號量信號將無法發(fā)出。線程在處理完共享資源后,應在離開的同時通過ReleaseSemaphore()函數(shù)將當前可用資源數(shù)加1。

CSemaphore semaphoreWrite(2,2); //資源最多訪問線程2個,當前可訪問線程數(shù)2個

UINT WriteA(LPVOID pParam)

{

??? CEdit *pEdit=(CEdit*)pParam;

??? pEdit->SetWindowText("");

??? WaitForSingleObject(semaphoreWrite.m_hObject,INFINITE);

??? CString str;

??? for(int i=0;i<10;i++)

??? {

??????? pEdit->GetWindowText(str);

??????? g_Array[i]=''A'';

??????? str=str+g_Array[i];

??? ??? pEdit->SetWindowText(str);

??????? Sleep(1000);

??? }

??? ReleaseSemaphore(semaphoreWrite.m_hObject,1,NULL);

??? return 0;

}

在信號量對象有信號的狀態(tài)下,線程執(zhí)行到WaitForSingleObject語句處繼續(xù)執(zhí)行,同時可用線程數(shù)減1;若線程執(zhí)行到WaitForSingleObject語句時信號量對象無信號,線程就在這里等待,直到信號量對象有信號線程才往下執(zhí)行。

?

#include

#include

#include

using namespacestd;

int nCount=50;???

DWORD ThreadID1;

DWORD ThreadID2;

DWORD ThreadID3;

HANDLE hMutex;

DWORD WINAPI TProc1(LPVOIDlParam)

{

??? while(nCount>0)

??? {

?????? Sleep(1);

?????? WaitForSingleObject(hMutex,INFINITE);

?????? printf("nCount=%d----線程n",nCount);

?????? nCount--;

?????? ReleaseMutex(hMutex);

??????

??? }

??? return 1;

}

DWORD WINAPI TProc2(LPVOIDlParam)

{

??? while(nCount>0)

??? {????? Sleep(1);

?????? WaitForSingleObject(hMutex,INFINITE);

?????? printf("nCount=%d----線程n",nCount);

?????? nCount--;

?????? ReleaseMutex(hMutex);

??? }

??? return 1;

}

?

?

int main(void)

{

??? hMutex=CreateMutex(NULL,NULL,NULL);

??? HANDLE h1=CreateThread(NULL,NULL,TProc1,NULL,NULL,&ThreadID1);

??? HANDLE h2=CreateThread(NULL,NULL,TProc2,NULL,NULL,&ThreadID2);

??? Sleep(5000);

??? return 0;

}

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉