日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ 线程同步之临界区CRITICAL_SECTION

發布時間:2023/12/18 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 线程同步之临界区CRITICAL_SECTION 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、臨界區臨界區又稱關鍵代碼段,指的是一小段代碼在代碼執行前,他需要獨占一些資源。程序中通常將多線程同時訪問的某個資源作為臨界區,需要定義一個CRITICAL_SECTION類型的變量,然后調用InitializeCriticalSection函數對變量進行初始化;函數聲明:VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection );lpCriticalSection:一個CRITICAL_SECTION結構指針,表示用于初始化的臨界區;InitializeCriticalSection函數在內部設置了CRITICAL_SECTION結構的某些成員變量,所以他不會失敗。為了將某一段代碼定義為臨界區,需要調用EnterCriticalSection函數;VOID WINAPI EnterCriticalSection(__inout LPCRITICAL_SECTION lpCriticalSection);該函數的作用是判斷是否有線程訪問臨界區資源,如果沒有,就改變CRITICAL_SECTION結構的成員變量的值,賦予當前線程訪問權,函數立即返回;如果有線程正在訪問資源,則進入等待狀態,直到沒有線程訪問。釋放資源函數:void WINAPI LeaveCriticalSection( _Inout_LPCRITICAL_SECTION lpCriticalSection);釋放CRITICAL_SECTION結構指針void WINAPI DeleteCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);二、學習案例用三個線程同時運行將一個變量增加到30;臨界區對象類#ifndef CAUTO_LOCK_H__#define CAUTO_LOCK_H__ class CAutoLock{public:?? ?CAutoLock();?? ?~CAutoLock(); ?? ?void Lock();?? ?void UnLock(); private:?? ?CRITICAL_SECTION m_Section;}; #endif#include "stdafx.h"#include "CAutoLock.h" CAutoLock::CAutoLock(){?? ?InitializeCriticalSection(&m_Section);?? ?//Lock();如果是用的時候只定義鎖對象,可以不手動進入臨界區和退出臨界區} CAutoLock::~CAutoLock(){?? ?DeleteCriticalSection(&m_Section);?? ?//UnLock();} void CAutoLock::Lock(){?? ?EnterCriticalSection(&m_Section);} void CAutoLock::UnLock(){?? ?LeaveCriticalSection(&m_Section);}三個線程創建類#ifndef _TEST_CRITICAL_SECTION_H__#define _TEST_CRITICAL_SECTION_H__#include "CAutoLock.h"class TestCriticalSection{public:?? ?TestCriticalSection();?? ?~TestCriticalSection(); ?? ?void StartThread();//開始線程函數 ?? ??? ?static DWORD __stdcall ThreadFun1(LPVOID lParam);//線程回調函數1?? ?static DWORD __stdcall ThreadFun2(LPVOID lParam);//線程回調函數2?? ?static DWORD __stdcall ThreadFun3(LPVOID lParam);//線程回調函數3 private:?? ?HANDLE m_hThread1; ? ? ? ?HANDLE m_hThread2;?? ?HANDLE m_hThread3; ?? ?CAutoLock m_lock;//三個線程公用的臨界區鎖 ?? ?static int m_nTotals;}; #endif#include "stdafx.h"#include "CCriticalSection.h"#include <iostream>using namespace std; int TestCriticalSection::m_nTotals = 0;//初始化靜態成員變量 TestCriticalSection::TestCriticalSection(){?? ?m_nTotals = 0; ? ? ? ?m_hThread1 = INVALID_HANDLE_VALUE;?? ?m_hThread2 = INVALID_HANDLE_VALUE;} TestCriticalSection::~TestCriticalSection(){?? ?if (m_hThread1 != NULL)?? ?{?? ??? ?CloseHandle(m_hThread1);?? ??? ?m_hThread1 = NULL;?? ?} ?? ?if (m_hThread2 != NULL)?? ?{?? ??? ?CloseHandle(m_hThread2);?? ??? ?m_hThread2 = NULL;?? ?} ?? ?if (m_hThread3 != NULL)?? ?{?? ??? ?CloseHandle(m_hThread3);?? ??? ?m_hThread3 = NULL;?? ?}} DWORD __stdcall TestCriticalSection::ThreadFun1(LPVOID lParam) //static只需要加在類定義里,類定義外面的函數定義前不能寫static{?? ?DWORD dRet = TRUE;?? ?TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);?? ?while(1)?? ?{?? ??? ?pThis->m_lock.Lock();?? ??? ?pThis->m_nTotals ++;?? ??? ?cout<<"ThreadFun1: m_nTotals "<<pThis->m_nTotals<<endl;?? ??? ?pThis->m_lock.UnLock();?? ??? ?Sleep(10);?? ??? ?if (pThis->m_nTotals == 30)?? ??? ?{?? ??? ??? ?break;?? ??? ?}?? ?} ?? ?return dRet;} DWORD __stdcall TestCriticalSection::ThreadFun2(LPVOID lParam){?? ?DWORD dRet = TRUE;?? ?TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);?? ?while(1)?? ?{?? ??? ?pThis->m_lock.Lock();?? ??? ?pThis->m_nTotals ++;?? ??? ?cout<<"ThreadFun2: m_nTotals "<<pThis->m_nTotals<<endl;?? ??? ?pThis->m_lock.UnLock();?? ??? ?Sleep(10);?? ??? ?if (pThis->m_nTotals == 30)?? ??? ?{?? ??? ??? ?break;?? ??? ?}?? ?}?? ?return dRet;} DWORD __stdcall TestCriticalSection::ThreadFun3(LPVOID lParam){?? ?DWORD dRet = TRUE;?? ?TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);?? ?while(1)?? ?{?? ??? ?pThis->m_lock.Lock();?? ??? ?pThis->m_nTotals ++;?? ??? ?cout<<"ThreadFun3: m_nTotals "<<pThis->m_nTotals<<endl;?? ??? ?pThis->m_lock.UnLock();?? ??? ?Sleep(10);?? ??? ?if (pThis->m_nTotals == 30)?? ??? ?{?? ??? ??? ?break;?? ??? ?}?? ?} ?? ?return dRet;} void TestCriticalSection::StartThread(){?? ?m_hThread1 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun1, this, ?0, NULL);?? ?m_hThread2 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun2, this, 0, NULL);?? ?m_hThread3 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun3, this, 0, NULL);}主函數:// CriticalSection.cpp : 定義控制臺應用程序的入口點。// #include "stdafx.h"#include "CCriticalSection.h" int _tmain(int argc, _TCHAR* argv[]){?? ?TestCriticalSection ?CriticalSectionObj;?? ?CriticalSectionObj.StartThread();?? ?Sleep(5000);?? ?system("pause");?? ?return 0;} 結果:如果代碼改成下面這樣,不加臨界區;資源訪問會沖突#include "stdafx.h"#include "CCriticalSection.h"#include <iostream>using namespace std; int TestCriticalSection::m_nTotals = 0; TestCriticalSection::TestCriticalSection(){?? ?m_nTotals = 0; ? ?m_hThread1 = INVALID_HANDLE_VALUE;?? ?m_hThread2 = INVALID_HANDLE_VALUE;} TestCriticalSection::~TestCriticalSection(){?? ?if (m_hThread1 != NULL)?? ?{?? ??? ?CloseHandle(m_hThread1);?? ??? ?m_hThread1 = NULL;?? ?} ?? ?if (m_hThread2 != NULL)?? ?{?? ??? ?CloseHandle(m_hThread2);?? ??? ?m_hThread2 = NULL;?? ?} ?? ?if (m_hThread3 != NULL)?? ?{?? ??? ?CloseHandle(m_hThread3);?? ??? ?m_hThread3 = NULL;?? ?}} DWORD __stdcall TestCriticalSection::ThreadFun1(LPVOID lParam) //static只需要加在類定義里,類定義外面的函數定義前不能寫static{?? ?DWORD dRet = TRUE;?? ?TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);?? ?while(1)?? ?{?? ??? ?//pThis->m_lock.Lock();?? ??? ?pThis->m_nTotals ++;?? ??? ?cout<<"ThreadFun1: m_nTotals "<<pThis->m_nTotals<<endl;?? ??? ?//pThis->m_lock.UnLock();?? ??? ?Sleep(10);?? ??? ?if (pThis->m_nTotals == 30)?? ??? ?{?? ??? ??? ?break;?? ??? ?}?? ?} ?? ?return dRet;} DWORD __stdcall TestCriticalSection::ThreadFun2(LPVOID lParam){?? ?DWORD dRet = TRUE;?? ?TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);?? ?while(1)?? ?{?? ??? ?//pThis->m_lock.Lock();?? ??? ?pThis->m_nTotals ++;?? ??? ?cout<<"ThreadFun2: m_nTotals "<<pThis->m_nTotals<<endl;?? ??? ?//pThis->m_lock.UnLock();?? ??? ?Sleep(10);?? ??? ?if (pThis->m_nTotals == 30)?? ??? ?{?? ??? ??? ?break;?? ??? ?}?? ?}?? ?return dRet;} DWORD __stdcall TestCriticalSection::ThreadFun3(LPVOID lParam){?? ?DWORD dRet = TRUE;?? ?TestCriticalSection * pThis = static_cast<TestCriticalSection*>(lParam);?? ?while(1)?? ?{?? ??? ?//pThis->m_lock.Lock();?? ??? ?pThis->m_nTotals ++;?? ??? ?cout<<"ThreadFun3: m_nTotals "<<pThis->m_nTotals<<endl;?? ??? ?//pThis->m_lock.UnLock();?? ??? ?Sleep(10);?? ??? ?if (pThis->m_nTotals == 30)?? ??? ?{?? ??? ??? ?break;?? ??? ?}?? ?} ?? ?return dRet;} void TestCriticalSection::StartThread(){?? ?m_hThread1 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun1, this, ?0, NULL);?? ?m_hThread2 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun2, this, 0, NULL);?? ?m_hThread3 = CreateThread(NULL, 0, &TestCriticalSection::ThreadFun3, this, 0, NULL);}結果可能會出現下面這種狀況

原文:https://blog.csdn.net/qwerdf10010/article/details/79657821?
?

總結

以上是生活随笔為你收集整理的C++ 线程同步之临界区CRITICAL_SECTION的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。