執行緒同步之互斥量加鎖解鎖 死鎖

2021-10-09 21:21:20 字數 3768 閱讀 9012

與互斥鎖相關api

互斥量(mutex)從本質上來說是一把鎖,在訪問共享資源前對互斥量進行加鎖,在訪問完成後釋放互斥量上的鎖。對互斥量進行加鎖後,任何其他試圖再次對互斥量加鎖的執行緒將會被阻塞直到當前執行緒釋放該互斥鎖。如果釋放互斥鎖時有多個執行緒阻塞,所有在該互斥鎖上的阻塞執行緒都會變成可執行狀態,第乙個變為可執行狀態的執行緒可以對互斥量加鎖,其他執行緒將會看到互斥鎖依然被鎖住,只能回去等待它重新變為可用。在這種方式下,每次只有乙個執行緒可以向前執行。

在設計時需要規定所有的執行緒必須遵守相同的資料訪問規則。只有這樣,互斥機制才能正常工作。作業系統並不會做資料訪問的序列化。如果允許其中的某個執行緒在沒有得到鎖的情況下也可以訪問共享資源,那麼即使其它的執行緒在使用共享資源前都獲取了鎖,也還是會出現資料不一致的問題。

互斥變數用pthread_mutex_t資料型別表示。在使用互斥變數前必須對它進行初始化,可以把它置為常量pthread_mutex_initializer(只對靜態分配的互斥量),也可以通過呼叫pthread_mutex_init函式進行初始化。如果動態地分配互斥量(例如通過呼叫malloc函式),那麼在釋放記憶體前需要呼叫pthread_mutex_destroy。

1. 建立及銷毀互斥鎖

#include

intpthread_mutex_init

(pthread_mutex_t *restrict mutex,

const pthread_mutexattr_t *restrict attr)

;int

pthread_mutex_destroy

(pthread_mutex_t

*restrict mutex)

;// 返回:若成功返回0,否則返回錯誤編號

要用預設的屬性初始化互斥量,只需把attr設定為null。

2. 加鎖及解鎖

#include

intpthread_mutex_lock

(pthread_mutex_t *restrict mutex)

;int

pthread_mutex_trylock

(pthread_mutex_t mutex)

;int

pthread_mutex_unlock

(pthread_mutex_t *restrict mutex)

;// 返回:若成功返回0,否則返回錯誤編號

如果執行緒不希望被阻塞,它可以使用pthread_mutex_trylock嘗試對互斥量進行加鎖。如果呼叫pthread_mutex_trylock時互斥量處於未鎖住狀態,那麼pthread_mutex_trylock將鎖住互斥量,不會出現阻塞並返回0,否則pthread_mutex_trylock就會失敗,不能鎖住互斥量,而返回ebusy。

**示例

#include

#include

//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);

int g_data=0;

pthread_mutex_t mutex;

//定義乙個互斥量也就是鎖

void

*func1

(void

*arg)

pthread_mutex_unlock

(&mutex)

;//給互斥量解鎖

}void

*func2

(void

*arg)

intmain()

ret=

pthread_create

(&t2,

null

,func2,

(void*)

¶m);if

(ret==0)

printf

("main : %ld \n",(

unsigned

long

)pthread_self()

);pthread_join

(t1,

null);

//用來等待程序t1退出

pthread_join

(t2,

null);

//用來等待程序t2退出

pthread_mutex_destroy

(&mutex)

;//銷毀這把鎖

return0;

}

指令碼可以這樣寫

clc@embed_learn:

~/xiancheng$ vi test.sh

clc@embed_learn:

~/xiancheng$ chmod +x test.sh

clc@embed_learn:

~/xiancheng$ .

/test.sh

//其中test.sh中寫入要執行的程式

實現程序t1滿足條件退出**

#include

#include

#include

//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);

int g_data=0;

//pthread_mutex_t mutex;

void

*func1

(void

*arg)}}

void

*func2

(void

*arg)

pthread_mutex_unlock

(&mutex);}

intmain()

ret=

pthread_create

(&t2,

null

,func2,

(void*)

¶m);if

(ret==0)

printf

("main : %ld \n",(

unsigned

long

)pthread_self()

);while(1

)pthread_join

(t1,

null);

pthread_join

(t2,

null);

pthread_mutex_destory

(&mutex)

;return0;

}

什麼情況下造成死鎖

死鎖 是指兩個或兩個以上的程序在執行過程中,由於競爭資源或彼此通訊而造成的一種阻塞現象,無外力作用,他們都將無法再推進下去。(一般需要兩個mutex)

**示例

void

*func1

(void

*arg)

pthread_mutex_unlock

(&mutex);}

void

*func2

(void

*arg)

參考博文:

Linux執行緒同步之互斥量加鎖 解鎖 死鎖

與互斥鎖相關api 互斥量 mutex 從本質上來說是一把鎖,在訪問共享資源前對互斥量進行加鎖,在訪問完成後釋放互斥量上的鎖。對互斥量進行加鎖後,任何其他試圖再次對互斥量加鎖的執行緒將會被阻塞直到當前執行緒釋放該互斥鎖。如果釋放互斥鎖時有多個執行緒阻塞,所有在該互斥鎖上的阻塞執行緒都會變成可執行狀態...

執行緒同步之互斥量

互斥量 當多個執行緒共享相同的記憶體時,需要每乙個執行緒看到相同的檢視。當乙個執行緒修改變數時,而其他執行緒也可以讀取或者修改這個變數,就需要對這些執行緒同步,確保他們不會訪問到無效的變數 在變數修改時間多於乙個儲存器訪問週期的處理器結構中,當儲存器的讀和寫這兩個週期交叉時,這種潛在的不一致性就會出...

執行緒同步之互斥量Mutex

前面的文章介紹了執行緒的建立 終止 連線和分離。本篇介紹執行緒的同步。多執行緒的難點是對共享資源的訪問,如何保證多個執行緒能夠 同時 訪問同乙個共享資源而又不引起衝突,就是執行緒同步的本質。互斥量用來確保共享資源同時只被乙個執行緒訪問。互斥量有兩種狀態 已鎖定 locked 和未鎖定 unlocke...