1. 程式人生 > >跨平臺的多執行緒互斥訪問控制(Mutex和Critical_Section)

跨平臺的多執行緒互斥訪問控制(Mutex和Critical_Section)

<1>首先解決跨平臺

  現在比較常用的平臺式Linux平臺和windows平臺,所以我們應該針對不同的平臺引用不同的標頭檔案

//平臺相關定義

#ifdef __linux
#define OS_LINUX
#endif

#if defined(_WIN32) || defined(_WIN64)
#define OS_WIN
#endif

//不同的平臺不同的標頭檔案定義

#ifdef OS_WIN
#include <windows.h>

#else

#include <pthread.h>

<2>不同平臺下的多執行緒訪問控制

//linux平臺

使用Posix執行緒庫的pthread_mutex系列函

 執行緒和執行緒的同步物件(互斥量,讀寫鎖,條件變數)都具有屬性。在修改屬性前都需要對該結構進行初始化。使用後要把該結構回收。我們用pthread_ mutexattr_init函式對pthread_mutexattr結構進行初始化,用pthread_mutexattr_destroy函式對該結構進行回收。

名稱::

pthread_mutexattr_init/pthread_mutexattr_destroy

功能:

初始化/回收pthread_mutexattr_t結構

標頭檔案:

#include <pthread.h>

函式原形:

int pthread_mutexattrattr_init(pthread_mutexattr_t *attr);

int pthread_mutexattrattr_destroy( pthread_mutexattr_t *attr );

引數:

attr    pthread_mutexattr_t結構變數

返回值:

若成功返回0,若失敗返回錯誤編號。

 pthread_mutexattr_init將屬性物件的值初始化為預設值。並分配屬性物件佔用的記憶體空間。

attr中pshared屬性表示用這個屬性物件建立的互斥鎖的作用域,它的取值可以是PTHREAD_PROCESS_PRIVATE(預設值,表示由這個屬性物件建立的互斥鎖只能在程序內使用)或PTHREAD_PROCESS_SHARED。

互斥量屬性分為共享互斥量屬性和型別互斥量屬性。兩種屬性分別由不同的函式得到並由不同的函式進行修改。pthread_mutexattr_getpshared和pthread_mutexattr_setpshared函式可以獲得和修改共享互斥量屬性。pthread_mutexattr_gettype和pthread_mutexattr_settype函式可以獲得和修改型別互斥量屬性。下面我們分別介紹。

名稱::

pthread_mutexattr_getpshared/pthread_mutexattr_setpshared

功能:

獲得/修改共享互斥量屬性

標頭檔案:

#include <pthread.h>

函式原形:

int pthread_mutexattrattr_ getpshared ( const pthread_attr_t *restrict attr,int*restrict pshared);

int pthread_mutexattrattr_ setpshared (  const pthread_attr_t *restrict attr,int pshared);

引數:

返回值:

若成功返回0,若失敗返回錯誤編號。

共享互斥量屬性用於規定互斥鎖的作用域。互斥鎖的域可以是程序內的也可以是程序間的。pthread_mutexattrattr_ getpshared可以返回屬性物件的互斥鎖作用域屬性。可以是以下值:PTHREAD_PROCESS_SHARED,PTHREAD_PROCESS_PRIVATE。如果互斥鎖屬性物件的pshared屬性被置PTHREAD_PROCESS_SHARED。那麼由這個屬性物件建立的互斥鎖將被儲存在共享記憶體中,可以被多個程序中的執行緒共享。如果pshared屬性被置為PTHREAD_PROCESS_PRIVATE,那麼只有和建立這個互斥鎖的執行緒在同一個程序中的執行緒才能訪問這個互斥鎖。

6

名稱::

pthread_mutexattr_gettype/pthread_mutexattr_settype

功能:

獲得/修改型別互斥量屬性

標頭檔案:

#include <pthread.h>

函式原形:

int pthread_mutexattrattr_ getpshared ( const pthread_attr_t *restrict attr,int*restrict pshared);

int pthread_mutexattrattr_ setpshared (  const pthread_attr_t *restrict attr,int pshared);

引數:

返回值:

若成功返回0,若失敗返回錯誤編號。

pthread_mutexattr_gettype函式可以獲得互斥鎖型別屬性。預設的互斥鎖型別屬性是PTHREAD_MUTEX_DEFAULT。

合法的型別屬性值有:

PTHREAD_MUTEX_NORMAL;

PTHREAD_MUTEX_ERRORCHECK;

PTHREAD_MUTEX_RECURSIVE;

PTHREAD_MUTEX_DEFAULT。

型別說明:

PTHREAD_MUTEX_NORMAL

這種型別的互斥鎖不會自動檢測死鎖。如果一個執行緒試圖對一個互斥鎖重複鎖定,將會引起這個執行緒的死鎖。如果試圖解鎖一個由別的執行緒鎖定的互斥鎖會引發不可預料的結果。如果一個執行緒試圖解鎖已經被解鎖的互斥鎖也會引發不可預料的結果。

PTHREAD_MUTEX_ERRORCHECK

這種型別的互斥鎖會自動檢測死鎖。如果一個執行緒試圖對一個互斥鎖重複鎖定,將會返回一個錯誤程式碼。如果試圖解鎖一個由別的執行緒鎖定的互斥鎖將會返回一個錯誤程式碼。如果一個執行緒試圖解鎖已經被解鎖的互斥鎖也將會返回一個錯誤程式碼。

PTHREAD_MUTEX_RECURSIVE

如果一個執行緒對這種型別的互斥鎖重複上鎖,不會引起死鎖,一個執行緒對這類互斥鎖的多次重複上鎖必須由這個執行緒來重複相同數量的解鎖,這樣才能解開這個互斥鎖,別的執行緒才能得到這個互斥鎖。如果試圖解鎖一個由別的執行緒鎖定的互斥鎖將會返回一個錯誤程式碼。如果一個執行緒試圖解鎖已經被解鎖的互斥鎖也將會返回一個錯誤程式碼。這種型別的互斥鎖只能是程序私有的(作用域屬性為PTHREAD_PROCESS_PRIVATE)。

PTHREAD_MUTEX_DEFAULT

這種型別的互斥鎖不會自動檢測死鎖。如果一個執行緒試圖對一個互斥鎖重複鎖定,將會引起不可預料的結果。如果試圖解鎖一個由別的執行緒鎖定的互斥鎖會引發不可預料的結果。如果一個執行緒試圖解鎖已經被解鎖的互斥鎖也會引發不可預料的結果。POSIX標準規定,對於某一具體的實現,可以把這種型別的互斥鎖定義為其他型別的互斥鎖。

應用互斥量需要注意的幾點

       1、互斥量需要時間來加鎖和解鎖。鎖住較少互斥量的程式通常執行得更快。所以,互斥量應該儘量少,夠用即可,每個互斥量保護的區域應則儘量大。

2、互斥量的本質是序列執行。如果很多執行緒需要領繁地加鎖同一個互斥量,

則執行緒的大部分時間就會在等待,這對效能是有害的。如果互斥量保護的資料(或程式碼)包含彼此無關的片段,則可以特大的互斥量分解為幾個小的互斥量來提高效能。這樣,任意時刻需要小互斥量的執行緒減少,執行緒等待時間就會減少。所以,互斥量應該足夠多(到有意義的地步),每個互斥量保護的區域則應儘量的少。

//win32平臺下的操作

class CThread

{

CThreadMutex()
{
InitializeCriticalSection(&m_hMutex);
}

///解構函式
~CThreadMutex()
{
DeleteCriticalSection(&m_hMutex);
}


int32_t Acquire(int32_t iTimeOut = INFINITE)
{
EnterCriticalSection(&m_hMutex);
return 0;
}

///離開臨界區
void Release()
{
LeaveCriticalSection(&m_hMutex);
}
private:
///核心互斥量控制代碼
CRITICAL_SECTIONm_hMutex;
};

相關推薦

跨平臺執行互斥訪問控制MutexCritical_Section

<1>首先解決跨平臺   現在比較常用的平臺式Linux平臺和windows平臺,所以我們應該針對不同的平臺引用不同的標頭檔案 //平臺相關定義 #ifdef __linux #define OS_LINUX #endif #if defined(_WIN32)

用WaitForSingleObject函式實現簡單的執行互斥訪問

今天是上班第一天,寫了一個簡單的執行緒互斥訪問練習了一下多執行緒。雖然以前寫過,但現在寫還是碰到蠻多問題,比如WaitForSingleObject()函式加在哪個位置(可以用WaitForSingleObject()等待前一個執行緒結束後然後開啟下一個執行緒以此達到同步的

執行互斥訪問資源的Demo

這個程式因為把執行緒的建立寫在了建構函式裡,不用顯式啟動執行緒,也因此有些臃腫。 #include <iostream> #include <stdlib.h> #include <thread> #include <mutex> #include

併發:等待執行完成的CountDownLatch倒數計時器

CountDownLatch允許一個或多個執行緒等待其他執行緒完成操作。 假如有這樣一個需求:我們需要解析一個Excel裡多個sheet的資料,此時可以考慮使用多執行緒,每個執行緒解析一個sheet裡的資料,等到所有的sheet都解析完之後,程式需要提示解析完成。在這個需求中,要實現主執行緒等待

Java執行面試知識點彙總超詳細總結

一、sleep()方法、wait()方法、yeild()方法、interrupt()方法、notify()、notifyAll()方法 1、sleep()方法: sleep方法為Thread的靜態方法; sleep方法的作用是讓執行緒休眠指定時間,在時間到

執行爬取圖片生產者-消費者模式

通過生產者-消費者模式實現多執行緒爬取圖片:   1、生產者通過不斷爬取網頁中圖片的url存入圖片佇列中   2、消費者通過圖片佇列中的url爬取圖片並下載到本地   3、多執行緒的方式,爬取與下載同時進行,直到子執行緒結束,輸出爬取時間   1 #多執行緒下載圖片 2 #生產者

執行同步-訊號量深入理解Semaphore

多執行緒同步之Semaphore (主要解決生產者消費者問題) 一 信標Semaphore 信標核心物件用於對資源進行計數。它們與所有核心物件一樣,包含一個使用數量,但是它們也包含另外兩個帶符號的3 2位值,一個是最大資源數量,一個是當前資源數量。最大資源數量用於標識信標

執行消費阻塞佇列生產者消費者模型

一.幾種主要的阻塞佇列ArrayBlockingQueue:基於陣列實現的一個阻塞佇列,在建立ArrayBlockingQueue物件時必須制定容量大小。並且可以指定公平性與非公平性,預設情況下為非公平的,即不保證等待時間最長的佇列最優先能夠訪問佇列。LinkedBlocki

執行佇列演算法優化雙端佇列(一

多執行緒佇列(Concurrent Queue)的使用場合非常多,高效能伺服器中的訊息佇列,並行演算法中的Work Stealing等都離不開它。對於一個佇列來說有兩個最主要的動作:新增(enqueue)和刪除(dequeue)節點。在一個(或多個)執行緒在對一個佇列進

c++11執行中的condition_variable生產者消費者示例

#include <iostream> #include <string> #include <th

執行學習筆記--02物件及變數的併發訪問

  1.學習目標          Synchronized物件監視器為Object時的使用      Synchronized物件監視器為Class時的使用    

C# 基礎十四C#單例模式:首先介紹 單執行執行、加鎖 單例模式。然後介紹單例模式的執行同步:執行有序訪問共享記憶體。

一、簡介 本篇文章將介紹如何使用單例模式,也就是類的例項化,在整個專案的生命週期內,只例項化一次。在單例模式中,往往可以看到如SourceCode.cs:這樣的結構的。 SourceCode.cs: public class Singleton { private static

作業系統Linux執行--互斥量實現同步

在訊號量中用sem_t結構表示,在互斥量中用pthread_mutexattr_t表示。 使用互斥變數以前,必須首先對它進行初始化,可以把它設定為常量PTHREAD_MUTEX_INITIALIZER(只適合用於靜態分配的互斥量), 也可以用pthread_mutexa

WPF執行直接訪問介面的控制元件的解決方式

WPF:Dispatcher.Invoke方法,只有在其上建立 Dispatcher的執行緒才可以直接訪問DispatcherObject。若要從不同於在其上建立 DispatcherObject的執行緒的某個執行緒訪問 DispatcherObject,請對與 DispatcherObject關聯的

C#執行非同步訪問winform中控制元件

我們在做winform應用的時候,大部分情況下都會碰到使用多執行緒控制介面上控制元件資訊的問題。然而我們並不能用傳統方法來做這個問題,下面我將詳細的介紹。       首先來看傳統方法:      public partial class Form1 : Form    

Linux執行計算Pi函式互斥沒起作用???

先上程式碼,求pi的公式就不貼了 #include <stdio.h> #include <stdlib.h> #include <pthread.h> #in

C#執行訪問winform控制元件

方法一:System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;  不推薦使用這種方式,禁止編譯器對跨執行緒訪問做檢查的方式實現。 方法二:使用delegate和invoke private

Java併發程式設計(03):執行併發訪問,同步控制

本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/java-base-parent) || [GitEE·點這裡](https://gitee.com/cicadasmile/java-base-parent) # 一、併發問題 多執行緒學習的時候,要面

WPF執行更改UI控制元件問題

無論是在WINFORM中,還是在WPF中,在涉及到複雜的邏輯關係時,如果在非同步執行緒中需要更改介面控制元件,需要通過以下機制進行操作,從而達到非同步更改介面控制元件的目的。 即   Dispatcher.Invoke(new Action(() =>   &nbs

32-執行--概述+Thread類+執行的建立方式繼承Thread類+實現Runnable介面+Runnable介面+執行的名稱+執行的狀態

一、概述 1、程序:對應的是一個應用程式在記憶體中的所屬空間。程序是不直接執行的,它只是在分配該應用程式的記憶體空間 注:如果一個程式在記憶體中開闢了空間,就代表它在執行。不執行要釋放空間 2、執行緒:程序中的一個負責程式執行的控制單元,也叫執行路徑。一個程序中可以有多個執行路徑,稱之為