程序間通訊往往意味著系統呼叫,核心態,使用者態的切換,其代價是不容忽視的。而執行緒是程序中的具體執行流,乙個程序中多個執行緒共享程序的資源,包含程序的虛擬位址空間,程序開啟的檔案描述符,程序組id等。
而執行緒間的通訊和同步由於處於同一位址空間下,也更加輕易和輕量級。
多執行緒之間訪問共享變數時,這些共享變數若每次只能被乙個執行緒進行訪問,稱為臨界資源。而對臨界資源的訪問在多執行緒環境下,如果不加以控制,很容易出現不一致性。
最常見的便是多執行緒售票問題。由於每個執行緒在執行售票(取得票數=》扣款=》票數i--=》寫回)時,不能在乙個原子操作中完成,cpu變對執行緒進行切換,其最終的結果是票數讀寫出現不一致性。
static int ticket=100;
void fun(int id)
pthread_exit(null);
}
執行結果:
出現了嚴重的資料不一致性。
解決此類臨界資源的互斥訪問問題一種思路便是互斥鎖:
mutex:鎖本身不具有強制性,設定執行緒在獲取鎖之後獨佔的訪問臨界資源,同一時間只能有乙個執行緒獲得鎖。
pthread中提供的pthread_mutex_t是一種linux下互斥鎖的實現方式。其基本的函式有:
pthread_mutex_init
互斥鎖動態初始化
pthread_mutex_lock
執行緒申請互斥鎖
pthread_mutext_trylock
非阻塞方式申請鎖
pthread_mutex_unlock
執行緒釋放互斥鎖
pthread_mutex_destory
銷毀互斥鎖
pthread_mutex_t mutex=pthread_mutex_initializer 靜態初始化
通過將查詢餘下票=》銷售=》減少票數 過程採取mutex互斥化
#include#include#include#include#includeusing namespace std;
static int ticket=100;
static pthread_mutex_t mutex=pthread_mutex_initializer;
void fun(int id)
cout << "當前票數:" << ticket << endl;
cout << "站台:" << id << "售票中" << endl;
ticket--;
cout << "剩餘票數:" << ticket << endl;
pthread_mutex_unlock(&mutex);//釋放鎖
int a;
//執行一段時間 模擬等待使用者過程
for(int i=0;i<100000;i++)
}}int main()
pthread_exit(null);
}
執行結果:
可以看到 各個執行緒成功的無誤的售出了100張票
將這段**注釋掉,也就是不斷的讓乙個執行緒申請鎖,釋放鎖
//執行一段時間 模擬等待使用者過程
for(int i=0;i<100000;i++)
執行結果:
可以看到,只有乙個執行緒不斷的獲取鎖、釋放鎖。也就是pthread_mutex並不會維護乙個等待鎖的佇列,而是讓所有執行緒競爭(在while迴圈下,第乙個執行緒總是能一直獲取鎖)。
互斥鎖提供了一種執行緒間同步的方式,其主要特點如下:
Linux 執行緒同步 互斥量(互斥鎖)
1 執行緒同步的目的是不管執行緒之間的執行如何穿插,其執行結果都是正確的。即保證多執行緒執行下結果的確定性。2 同步就是讓所有執行緒按照一定的規則執行,使得其正確性和效率都有跡可循,即執行緒同步就是對執行緒之間的穿插進行控制。3 每個物件都對應於乙個 互斥鎖 的標記,這個標記用來保證在任一時刻,只能...
執行緒間同步機制 互斥鎖
互斥以排他方式防止共享資料被併發修改。互斥量從本質來說是一把鎖,是乙個二元變數,其狀態為開鎖 允許0 和上鎖 禁止1 在訪問共享資源前對互斥量進行設定 加鎖 在訪問完成後釋放 解鎖 互斥量。1 在訪問該資源前,首先申請該互斥鎖,如果該互斥鎖處於開鎖狀態,則申請到該鎖物件,並立即占有該鎖 使該鎖處於鎖...
執行緒間互斥鎖
一 兩種使用方式 1.靜態方式 pthread mutex t mtx pthread mutex initializer 2.動態方式 include int pthread mutex init pthread mutex t mutex,const pthread mutexattr t at...