互斥量(也稱為互斥鎖)出自posix
執行緒標準,可以用來同步同一程序中的各個執行緒。當然如果乙個互斥量存放在多個程序共享的某個記憶體區中,那麼還可以通過互斥量來進行程序間的同步。
互斥量,從字面上就可以知道是相互排斥的意思,它是最基本的同步工具,用於保護臨界區(共享資源),以保證在任何時刻只有乙個執行緒能夠訪問共享的資源。
互斥量型別宣告為pthread_mutex_t
資料型別,在
中有具體的定義。
1互斥量初始化和銷毀
/* initialize a mutex. */
int pthread_mutex_init (pthread_mutex_t *__mutex, __const pthread_mutexattr_t *__mutexattr);
/* destroy a mutex. */
int pthread_mutex_destroy (pthread_mutex_t *__mutex);
上面兩個函式分別由於互斥量的初始化和銷毀。
如果互斥量是靜態分配的,可以通過常量進行初始化,如下:
pthread_mutex_t mlock = pthread_mutex_initializer;
當然也可以通過pthread_mutex_init()
進行初始化。對於動態分配的互斥量由於不能直接賦值進行初始化就只能採用這種方式進行初始化,
pthread_mutex_init()
的第二個引數是互斥量的屬性,如果採用預設的屬性設定,可以傳入
null。
當不在需要使用互斥量時,需要呼叫pthread_mutex_destroy()
銷毀互斥量所占用的資源。
2互斥量的屬性設定
/* 初始化互斥量屬性物件 */
int pthread_mutexattr_init (pthread_mutexattr_t *__attr);
/* 銷毀互斥量屬性物件 */
int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr);
/* 獲取互斥量屬性物件在程序間共享與否的標誌 */
int pthread_mutexattr_getpshared (__const pthread_mutexattr_t *__restrict __attr, int *__restrict __pshared);
/* 設定互斥量屬性物件,標識在程序間共享與否 */
int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr, int __pshared);
互斥量在初始化的時候pthread_mutex_init
的第二個引數是互斥量的屬性,如果為
null
空指標,那麼就使用預設屬性。
互斥量屬性的資料型別為pthread_mutexattr_t
,它的初始化和銷毀和互斥量類似。一旦互斥量屬性物件被初始化後,就可以通過呼叫不同的函式啟用或禁止特定的屬性。這裡列出了乙個設定特定屬性的函式:pthread_mutexattr_setpshared,可以用於指定互斥量在不同程序間共享,這樣可以通過互斥量來同步不同的程序,當然前提是該互斥量位於程序間的共享記憶體區。
pthread_mutexattr_setpshared()函式的第二個引數__pshared用於設定是否程序間共享,其值可以是pthread_process_private或
pthread_process_shared
,後者是設定程序間共享。
下面是使互斥量可以在程序間共享的大致過程:
pthread_mutex_t *psharedmutex; //指向共享記憶體區的互斥量
pthread_mutexattr_t mutexattr; //互斥量屬性
psharedmutex = /*乙個指向共享記憶體區的指標*/;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr, pthread_process_shared);
pthread_mutex_init(psharedmutex, &mutexattr);
3互斥量的使用
/* try locking a mutex. */
int pthread_mutex_trylock (pthread_mutex_t *__mutex);
/* lock a mutex. */
int pthread_mutex_lock (pthread_mutex_t *__mutex);
/* unlock a mutex. */
int pthread_mutex_unlock (pthread_mutex_t *__mutex);
這幾個函式都很簡單,通過pthread_mutex_lock()函式獲得訪問共享資源的許可權,如果已經有其他執行緒鎖住互斥量,那麼該函式會是執行緒阻塞指定該互斥量解鎖為止。
pthread_mutex_trylock()
是對應的非阻塞函式,如果互斥量已被占用,它會返回乙個
ebusy
錯誤。訪問完共享資源後,一定要通過pthread_mutex_unlock()函式,釋放占用的互斥量。允許其他執行緒訪問該資源。
這裡要強調的是:互斥量是用於上鎖的,不能用於等待。
簡單說就是,互斥量的使用流程應該是:執行緒占用互斥量,然後訪問共享資源,最後釋放互斥量。而不應該是:執行緒占用互斥量,然後判斷資源是否可用,如果不可用,釋放互斥量,然後重複上述過程。這種行為稱為輪轉或輪詢,是一種浪費cpu
時間的行為。
下面是乙個測試**,模擬同步問題中經典的生產者消費者問題。
#include #include #include #include #include using namespace std;
pthread_mutex_t mutex;
queueproduct;
void * produce(void *ptr)
}void * consume(void *ptr)
++i;
cout<<"consume:"在判斷佇列中是否有資料的時候就是通過輪詢的方式進行的,這種行為很浪費
cpu資源,可以通過條件變數來解決這個問題。
jun 25, 2013 pm 23:32 @library
執行緒同步之互斥量
互斥量 當多個執行緒共享相同的記憶體時,需要每乙個執行緒看到相同的檢視。當乙個執行緒修改變數時,而其他執行緒也可以讀取或者修改這個變數,就需要對這些執行緒同步,確保他們不會訪問到無效的變數 在變數修改時間多於乙個儲存器訪問週期的處理器結構中,當儲存器的讀和寫這兩個週期交叉時,這種潛在的不一致性就會出...
Linux 執行緒同步 互斥量(互斥鎖)
1 執行緒同步的目的是不管執行緒之間的執行如何穿插,其執行結果都是正確的。即保證多執行緒執行下結果的確定性。2 同步就是讓所有執行緒按照一定的規則執行,使得其正確性和效率都有跡可循,即執行緒同步就是對執行緒之間的穿插進行控制。3 每個物件都對應於乙個 互斥鎖 的標記,這個標記用來保證在任一時刻,只能...
執行緒同步之互斥量Mutex
前面的文章介紹了執行緒的建立 終止 連線和分離。本篇介紹執行緒的同步。多執行緒的難點是對共享資源的訪問,如何保證多個執行緒能夠 同時 訪問同乙個共享資源而又不引起衝突,就是執行緒同步的本質。互斥量用來確保共享資源同時只被乙個執行緒訪問。互斥量有兩種狀態 已鎖定 locked 和未鎖定 unlocke...