1. 程式人生 > >C++ 臨界區 多執行緒同步互斥

C++ 臨界區 多執行緒同步互斥

臨界區(Critical Section) 保證在某一時刻只有一個執行緒能訪問資料的簡便辦法。在任意時刻只允許一個執行緒對共享資源進行訪問。如果有多個執行緒試圖同時訪問臨界區,那麼在有一個線 程進入後其他所有試圖訪問此臨界區的執行緒將被掛起,並一直持續到進入臨界區的執行緒離開。臨界區在被釋放後,其他執行緒可以繼續搶佔,並以此達到用原子方式操 作共享資源的目的。 臨界區包含兩個操作原語: EnterCriticalSection() 進入臨界區 LeaveCriticalSection() 離開臨界區 EnterCriticalSection()語句執行後代碼將進入臨界區以後無論發生什麼,必須確保與之匹配的 LeaveCriticalSection()都能夠被執行到。否則臨界區保護的共享資源將永遠不會被釋放。雖然臨界區同步速度很快,但卻只能用來同步本 程序內的執行緒,而不可用來同步多個程序中的執行緒。

使用臨界區的步驟

1 . 申請一個臨界區變數  CRITICAL_SECTION gSection;

2. 初始化臨界區  InitializeCriticalSection(&gSection);

3. 使用臨界區 EnterCriticalSection(&gSection); ..省略程式碼..LeaveCriticalSection(&gSection);

4.釋放臨界區 DeleteCriticalSection(&gSection);

例項程式碼如下:

#include <iostream>
#include <windows.h>
#include <PROCESS.H>

using namespace std;
//用一個CRITICAL_SECTION 結構體和需要同步的資料關聯起來
typedef struct tagSafePtr
{
    int* pInt;
    CRITICAL_SECTION cs;
}StSafePtr,*PStSafePtr;

CRITICAL_SECTION gSection;

class auto_lock
{
public :
    auto_lock(PCRITICAL_SECTION pcs)
    {
        _pcs=pcs;
        EnterCriticalSection(_pcs);
    }
    ~auto_lock()
    {
        LeaveCriticalSection(_pcs);
    }
private:
    PCRITICAL_SECTION _pcs;
};
unsigned _stdcall thread1(void* ptr)
{
    EnterCriticalSection(&gSection);
    cout<<"thread 1"<<endl;
    Sleep(2000);
    PStSafePtr pSafePtr=(PStSafePtr)ptr;
    LeaveCriticalSection(&gSection);
    if (pSafePtr)
    {
        //在獲取被同步的資料前,要先進入臨界區,保證同時只有一個執行緒訪問
        //EnterCriticalSection(&(pSafePtr->cs));
        auto_lock m(&pSafePtr->cs);
        Sleep(10);
        delete pSafePtr->pInt;
        pSafePtr->pInt=0;
        cout<<"delete ptr!"<<endl;
        //多執行緒任務退出臨界區
        //LeaveCriticalSection(&(pSafePtr->cs));
    }
    return 0;
}

unsigned _stdcall thread2(void* ptr)
{
    EnterCriticalSection(&gSection);
    cout<<"therad 2"<<endl;
    Sleep(2000);
    PStSafePtr pSafePtr=(PStSafePtr)ptr;
    LeaveCriticalSection(&gSection);
    if (pSafePtr)
    {
        //在獲取被同步的資料前,先要進入臨界區,保證同一時刻只有一個執行緒訪問
        //EnterCriticalSection(&(pSafePtr->cs));
        // 利用類 進入臨界區 
        auto_lock m(&pSafePtr->cs);
        int* p =pSafePtr->pInt;
        if(p)
        {
            *p=100;
            cout<<*p<<endl;
        }
        else
        {
            cout<<" p is null.."<<endl;
        }
        //任務結束,退出臨界區
        //LeaveCriticalSection(&(pSafePtr->cs));
    }
    return 0;
}

int main()
{
    StSafePtr st;
    //初始化臨界區
    InitializeCriticalSection(&st.cs);
    InitializeCriticalSection(&gSection);
    st.pInt=new int (10);
    HANDLE h1=(HANDLE)_beginthreadex(0,0,thread1,&st,0,0);
    HANDLE h2=(HANDLE)_beginthreadex(0,0,thread2,&st,0,0);
    ::WaitForSingleObject(h1,INFINITE);
    CloseHandle(h1);
    ::WaitForSingleObject(h2,INFINITE);
    CloseHandle(h2);
    delete st.pInt;
    //清理資源
    DeleteCriticalSection(&st.cs);
    DeleteCriticalSection(&gSection);
    return 0;
}


相關推薦

C++ 臨界 執行同步互斥

臨界區(Critical Section) 保證在某一時刻只有一個執行緒能訪問資料的簡便辦法。在任意時刻只允許一個執行緒對共享資源進行訪問。如果有多個執行緒試圖同時訪問臨界區,那麼在有一個線 程進入後其他所有試圖訪問此臨界區的執行緒將被掛起,並一直持續到進入臨界區的執行緒離

C++ 訊號量 執行同步互斥

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">訊號量(Semaphores)   </span>訊號量物件

執行,同步,互斥(生產者/消費者)

資料汙讀:bool 的 true   和   bool 的 false , 當1執行緒執行true時讀檔案, 為false時2執行緒讀檔案,但是由於執行緒的cpu分時複用,可能還會執行 true 操作 , 導致讀入資料異常 .    &

執行同步互斥的四個實現方法圖

一、引言 這篇文章記錄是來源於Windows多執行緒系列的學習筆記,表為原創,實為轉載文章,只是為了讓自己學的明白,稍微整理了下而已,在此向“MoreWindows”大神致敬! 二、關鍵段與互斥量Mutex 名稱 建立或初始化 銷燬

執行同步-互斥物件(深入理解Mutex)

多執行緒之執行緒同步Mutex (功能與Critial Sections相同,但是屬於核心物件,訪問速度較慢,可以被不同程序呼叫)一 Mutex 互斥物件(mutex)核心物件能夠確保執行緒擁有對單個資源的互斥訪問權。實際上互斥物件是因此而得名的。互斥物件包含一個使用數量,

執行同步互斥例項——執行共享資料

      • 例項問題         設計4個執行緒,其中兩個執行緒每次對j增加1,另外兩個執行緒對j每次減少1,寫出程式。這是一道java執行緒面試的面試題,這道題在網上有很多答案。那麼,答案是

執行同步互斥例項——使用synchronized實現執行通訊和互斥

執行緒互斥概念       執行緒互斥是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。 實現執行緒同步互斥的四種方式    

C++執行同步效率對比之臨界和原子鎖

多執行緒程式設計經常遇到資料同步問題,通常的做法就是加鎖,之前個人常用臨界區(CTITICAL_SECTION),最近開發高效率程式,尋求更高效的同步方式,才有了對原子鎖的研究。經測試,原子鎖效率確實比臨界區高,用資料衡量,原子鎖的效率是臨界區的5倍左右。 測試方法: 1、

Visual C++網路程式設計經典案例詳解 第3章 執行與非同步套接字程式設計 實現執行同步 互斥物件 使用API函式操作互斥物件

互斥物件和臨界區物件和事件物件作用一樣 用於實現執行緒同步 互斥物件可以線上程中使用 CreateMutex()建立並返回互斥物件 原型如下 HANDLE CreateMutex(   LPSECURITY_ATTIRIBUTES lpMutexAttributes,  

Visual C++網路程式設計經典案例詳解 第3章 執行與非同步套接字程式設計 實現執行同步 互斥物件 程式的唯一執行

互斥物件可在程序中使用 使用者在程序建立互斥物件實現程式例項唯一執行 建立控制檯工程 #include<windows.h>                                //包含標頭檔案 #include<stdio.h> in

C++執行同步之Mutex(互斥量)

一、互斥量Mutex同步多執行緒 1、Win32平臺 相關函式和標頭檔案 #include <windows.h> HANDLE CreateMutex( LPSECURITY_ATTRIBUTESlpMutexAttributes

【VS2010】C++執行同步互斥簡單運用

繼以往的想法,寫這點文字,貼上點程式碼,是為了增加自己的記憶,也希望能幫助到需要幫助的人。 1.  互斥量,Mutex #include <Windows.h> #include <iostream> usingnamespace

執行同步之 CriticalSection(臨界)

先看一段程式, 程式碼檔案: unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCt

C++執行同步技巧(二) ---事件

簡介 Windows線上程控制方面提供了多種訊號處理機制,其中一種便是使用 CreateEvent() 函式建立事件,然後使用訊號控制執行緒執行。其中將事件變為有訊號可使用 SetEvent() 函式,將事件訊號復位(變為無訊號)可使用 ResetEvent(

秒殺執行第七篇 經典執行同步 互斥量Mutex

閱讀本篇之前推薦閱讀以下姊妹篇: 《秒殺多執行緒第四篇一個經典的多執行緒同步問題》 《秒殺多執行緒第五篇經典執行緒同步關鍵段CS》 《秒殺多執行緒第六篇經典執行緒同步事件Event》   前面介紹了關鍵段CS、事件Event在經典執行緒同步問題中的使用。本篇介紹用互斥量Mu

執行同步互斥

多執行緒執行緒基礎操作 關於本篇部落格的更多程式碼:GitHub連結 執行緒的同步與互斥,學習生產者消費者模型及應用場景 執行緒安全:生產者與消費者模型,讀寫者模型,同步與互斥的實現,互斥鎖,條件變數,posix訊號量,讀寫鎖,自旋鎖 大部分情況,執行緒使用的資料都是區域性變

最簡單的實現Linux C++執行互斥訪問

#include <stdlib.h> #include <string.h> #include <iostream> #include <unistd.h> #include <errno.h> #include <pthrea

c++ 執行 鎖(互斥鎖)

多執行緒程式,如果涉及到對共享資源的併發讀寫,就會產生資源爭用(Data Race)。解決資源爭用,最直接的想法是引入鎖,對併發讀寫的資料進行保護(更高階的則包括無鎖程式設計—— Lock Free Programming)。但是,鎖又有很多種類,例如:自旋鎖(Spinlock)、互斥鎖(Mutex

執行同步互斥(3)

在進行多執行緒程式設計時,難免還要碰到兩個問題,那就執行緒間的互斥與同步: 執行緒同步是指執行緒之間所具有的一種制約關係,一個執行緒的執行依賴另一個執行緒的訊息,當它沒有得到另一個執行緒的訊息時應等待,直到訊息到達時才被喚醒。 執行緒互斥是指對於共享的程序系統資源,在各單個執行緒訪問時的排它性。當有若干個執行

執行同步互斥有哪幾種實現方法?

執行緒間的同步方法大體可分為兩類:使用者模式和核心模式。顧名思義,核心模式就是指利用系統核心物件的單一性來進行同步,使用時需要切換核心態與使用者態,而使用者模式就是不需要切換到核心態,只在使用者態完成操作。使用者模式下的方法有:原子操作(例如一個單一的全域性變數),臨界區。核