1. 程式人生 > >2執行緒同步-C++11中的互斥鎖

2執行緒同步-C++11中的互斥鎖

C11中mutex標頭檔案內容

Mutex

類,基本的互斥鎖

recursive_mutex

類, 同一執行緒可以遞迴呼叫的互斥鎖

timed_mutex

類,在指定的時間內能返回的鎖

recursive_timed_mutex

類,在指定的時間內能返回且同一執行緒能遞迴呼叫的鎖

adopt_lock_t

空結構體,用於控制unique_lock,lock_guard的處理策略(假定當前執行緒已經獲得互斥物件的所有權,所以不再請求鎖。)

例如:std::unique_lock<std::mutex> lck(mt, std:: adopt_lock);

defer_lock_t

空結構體,用於控制unique_lock 的處理策略(不請求鎖)

try_to_lock_t

空結構體,用於控制unique_lock 的處理策略(嘗試請求鎖,但不阻塞執行緒,鎖不可用時也會立即返回。)

lock_guard

建構函式自動加鎖,解構函式自動釋放鎖。

unique_lock

具備lock_guard的功能外,增加增加了解鎖,加鎖等功能。等於是更小粒度的資源控制。

swap

交換兩個互斥鎖

try_lock

嘗試同時鎖多個物件。

lock

同時鎖住多個鎖物件。

once_flag

結構體用於儲存函式呼叫記錄標誌。

call_once

保證函式只被呼叫一次,用once_flag當作記錄看是否已經被呼叫。

C11中的鎖在linux 平臺上的實現

就是對pthread_mutex物件的封裝,具備了pthread_mutex的所有特性。

C11中的鎖在win 平臺上的實現

是對臨界區的封裝嗎? 答案是否定的。

通過對鎖函式上鎖的跟蹤發現如下程式碼:

boolcritical_section::_Acquire_lock(void * _PLockingNode,bool _FHasExternalNode)

{

LockQueueNode * pNewNode =reinterpret_cast<LockQueueNode*>(_PLockingNode);

LockQueueNode * pActiveNode =reinterpret_cast<LockQueueNode*>(&_M_activeNode);

if (pNewNode->m_pContext == pActiveNode->m_pContext)

{

throw improper_lock("Lock alreadytaken");

}

LockQueueNode * pPrevious =reinterpret_cast<LockQueueNode*>(InterlockedExchangePointer(&_M_pTail, pNewNode));

// 通過原子操作對指標進行判斷,看是否已經上鎖,NULL表示未上鎖

if (pPrevious == NULL)

{

_M_pHead = pNewNode;

pNewNode->UpdateQueuePosition(pActiveNode);

pNewNode->UnblockWithoutContext();

pNewNode->TryCompensateTimer();

}

else

{

pNewNode->UpdateQueuePosition(pPrevious);

pPrevious->m_pNextNode = pNewNode;

//  在下面的函式中去競爭鎖

 pNewNode->Block(pActiveNode->m_ticketState);

 if(pNewNode->m_trigger != TriggeredByTimeout)

{

pNewNode->UpdateQueuePosition(pActiveNode);

}

}

if (_FHasExternalNode)

{

pActiveNode->Copy(pNewNode);

_M_pHead = pNewNode;

}

returnpNewNode->m_trigger != TriggeredByTimeout;

}

我們繼續跟蹤競爭鎖的程式碼

void Block(unsignedint currentTicketState =0)

{

unsignedint numberOfProcessors =Concurrency::GetProcessorCount();

_CONCRT_ASSERT(numberOfProcessors> 0);

if (!IsPreviousBlocked())

{

unsignedint placeInLine =IsTicketValid() ? ((m_ticketState >> NumberOfBooleanStates) -(currentTicketState >> NumberOfBooleanStates)) : 1;

_CONCRT_ASSERT(placeInLine >0);

if (placeInLine <=numberOfProcessors + TicketThreshold)

{

constunsignedint defaultSpin =_SpinCount::_Value();

unsignedint totalSpin =defaultSpin + (defaultSpin * (placeInLine - 1)) / (numberOfProcessors +TicketThreshold);

_SpinWaitNoYield spinWait;

spinWait._SetSpinCount(totalSpin);

  // 在這邊開始自旋,自旋到一定次數後,跳出這個迴圈

while (IsBlocked() &&spinWait._SpinOnce())

{

}

}

}

//如果自旋完成後,依然得不到鎖,本執行緒進入這個函式後,陷入核心態開始睡眠

m_pContext->Block();

}

睡眠函式如下:

void ExternalContextBase::Block()

{

ASSERT(this ==SchedulerBase::FastCurrentContext());

TraceContextEvent(CONCRT_EVENT_BLOCK,TRACE_LEVEL_INFORMATION, m_pScheduler->Id(), m_id);

if(InterlockedIncrement(&m_contextSwitchingFence) == 1)

{

WaitForSingleObjectEx(m_hBlock,INFINITE, FALSE);

}

else

{

}

}

呼叫WaitForSingleObjectEx函式而進入核心態。

總結

C11鎖的原理就是先自旋,不能成功後,執行WaitForSingleObjectEx函式後進入核心態睡眠。

通過跟蹤windos提供的臨界區程式碼,發現也有原子操作,進入核心態睡眠。在作業系統提供的功能下,兩種方法是同級的,來自於不同產品的包裝而已。

相關推薦

2執行同步-C++11互斥

C11中mutex標頭檔案內容 Mutex 類,基本的互斥鎖 recursive_mutex 類, 同一執行緒可以遞迴呼叫的互斥鎖 timed_mutex 類,在指定的時間內能返回的鎖 recursive_timed_mutex 類,在指定的時間內能返回且同一執行緒能遞迴

3執行同步-C++11的條件變數

在C11標頭檔案<condition_variable>中包含了如下內容 cv_status 條件等待結果的列舉。 condition_variable 條件變數的主要類,用於實現執行緒同步。 condition_variable_any 是對condition

Posix執行C++11執行學習

在C++11引進多執行緒之前,我們不得不使用POSIX pthreads,因此本文主要包括三部分: POSIX多執行緒實踐 C++11 多執行緒實踐 類成員函式作為執行緒函式的實現 一、POSIX多執行緒實踐 一個簡單執行緒的實現 建立一個執行緒,該執

C++之多執行C++11 thread.h檔案實現多執行

轉載自: 與 C++11 多執行緒相關的標頭檔案 C++11 新標準中引入了四個標頭檔案來支援多執行緒程式設計,他們分別是<atomic> ,<thread>,<mutex>,<condition_variable>和&l

執行同步--協同方式和互斥方式

參考部落格:http://www.cnblogs.com/kennyMc/archive/2012/12/15/2818887.html    參考部落格:http://www.cnblogs.com/xilentz/archive/2012/11/13/2767317.h

執行C#.NET使用BackgroundWorker在模態對話方塊顯示進度條

我們使用C#.NET編寫WinForm程式時,有時候為了實現在模態對話方塊中實時顯示後臺操作的進度,這個時候需要藉助於多執行緒操作在子窗體中顯示進度條狀態,在父窗體中進行後臺操作。你可以在Thread類中自己建立兩個執行緒以完成這個操作,不過C#.NET提供了Backgro

【Windows】執行漫談——.NET執行同步之Interlocked和ReadWrite

摘要: 本系列意在記錄Windwos執行緒的相關知識點,包括執行緒基礎、執行緒排程、執行緒同步、TLS、執行緒池等。 這篇來說說靜態的Interlocked類和ReadWrite鎖 .NET中的Interlock

C++11互斥對程式效能的影響

在多執行緒中,對資料的保護機制,我們用到了互斥量、臨界區、讀寫鎖、條件變數等方法。一直以來都有些擔心鎖會降低程式的效能,儘管它是必須的,但究竟它能降低多少呢?那只有靠資料說話,下面的程式碼是2個執行緒同時操作一個變數:class TestA { public: explic

程序間通訊機制(管道、訊號、共享記憶體/訊號量/訊息佇列)、執行間通訊機制(互斥、條件變數、posix匿名訊號量)

(1)系統中每個訊號量的資料結構(sem)struct sem {     int semval; /* 訊號量的當前值 */     unsigned short  semzcnt;  /* # waiting for zero */     unsigned short  semncnt;  /* # w

執行互斥C++11std::thread和std::mutex的用法)

執行緒 0 首先是曾經在MultiCMOS專案中用到的: #include <thread> //包含標頭檔案 class IDataProcessUnit { protected:

C++11併發學習之三:執行同步

1.<mutex> 標頭檔案介紹  (1)Mutex系列類(四種) std::mutex,最基本的 Mutex 類。 std::recursive_mutex,遞迴 Mutex 類。 std::time_mutex,定時 Mutex 類。 std::recursive_ti

C++11併發學習之四:執行同步(續)

有時候,在第一個執行緒完成前,可能需要等待另一個執行緒執行完成。C++標準庫提供了一些工具可用於這種同步操作,形式上表現為條件變數(condition variable)和期望(future)。 一.條件變數(condition variable) C++標準庫對條件變數有兩套實現:std::c

C++11的多執行

C++標準庫的多執行緒使用, 示例程式碼如下: #include<iostream> #include<thread> //C++11 //#include<exc

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

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

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

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

c++11執行Join函式

寫在前面 Join函式作用: Join thread The function returns when the thread execution has completed.//直到執行緒完成函式才返回 This synchronizes the moment t

python爬蟲入門八:多程序/多執行緒 python佇列Queue Python多執行緒2)——執行緒同步機制 python學習筆記——多程序共享記憶體Value & Array python 之 多程序 Python多程序 Python 使用multiprocessing 特別耗記

什麼是多執行緒/多程序 引用蟲師的解釋: 計算機程式只不過是磁碟中可執行的,二進位制(或其它型別)的資料。它們只有在被讀取到記憶體中,被作業系統呼叫的時候才開始它們的生命期。 程序(有時被稱為重量級程序)是程式的一次執行。每個程序都有自己的地址空間,記憶體,資料棧以及其它記錄其執行軌跡的輔助資料

Linux多執行學習(2)--執行同步互斥及死問題(互斥量和條件變數)

Linux多執行緒學習總結 一.互斥量 1.名詞理解 2.什麼是互斥量(mutex) 3.互斥量的介面 3.1 初始化訊號量 3.2 銷燬訊號量 3.3 互斥量加鎖和解鎖

C/C++多執行執行同步互斥與訊號量)

參考連結2.中寫的非常好,簡單易懂,上手快,非常好的博文。使用多執行緒及互斥鎖樣例:#include <iostream> #include <windows.h> using namespace std; HANDLE hMutex = NULL;

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

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