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++11中std::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