linux c程式設計 執行緒互斥二 執行緒死鎖

2022-05-30 21:12:11 字數 4329 閱讀 9802

死鎖就是不同的程式在執行時因為某種原因發生了阻塞,進而導致程式不能正常執行。阻塞程式的原因通常都是由於程式沒有正確使用臨界資源。

我們舉個日常生活中的例子來比喻死鎖。我們把馬路上行駛的汽車比作執行著的程式,把馬路比作臨界資源,如果有兩輛汽車相互碰撞,就會把車停在馬路上,這樣的話他們一直占用著馬路這個臨界資源。其它的汽車不能正常通過馬路,於是整條路上的汽車都無法在馬路上正常行駛,馬路也被汽車堵的水洩不通。整個交通都癱瘓了,這就是「死鎖」。造成死鎖的原因就是發生車禍的汽車占用了馬路這種臨界資源,以至於其它汽車無法在馬路上正常行駛。

在實際的程式中造成死鎖的原因有兩種:

1 同乙個執行緒對已經加鎖的互斥量再次加鎖;

2 執行緒a對互斥量一加鎖,同時等待互斥量二被解鎖;而此時,執行緒b對互斥量二加鎖,同時等待互斥量一被解鎖;

首先來看第一種現象:

int value=0;

pthread_mutex_t mutex_value_tmp1=pthread_mutex_initializer;

void read_data(){

printf("data=%d\n",value);

printf("end reading data\n");

void threading_func1(){

int i=0;

int res=0;

pthread_t thread_id;

thread_id=pthread_self();

printf("thread id :%d\n",thread_id);

while(i<4){

res=pthread_mutex_lock(&mutex_value_tmp1);  #第一次加鎖

if (res !=0){

printf("thread mutex failed\n");

read_data();

res=pthread_mutex_lock(&mutex_value_tmp1);  #第二次加鎖

if (res !=0){

printf("thread mutex failed\n");

res=pthread_mutex_unlock(&mutex_value_tmp1);  #釋放鎖;

printf("res=%d\n",res);

if (res !=0){

printf("mutex unlock failed\n");

sleep(2000);

pthread_exit((void *)2);

結果執行如下:

當執行緒2再次執行的時候,由於無法獲取鎖,因此發生死鎖

這種情況下為了避免阻塞。需要用到pthread_mutex_tryloc。

函式pthread_mutex_trylock是pthread_mutex_lock的非阻塞版本。如果mutex引數所指定的互斥鎖已經被鎖定的話,呼叫pthread_mutex_trylock函式不會阻塞當前執行緒,而是立即返回乙個值來描述互斥鎖的狀況。將上面**中的pthread_mutex_lock全部替換為pthread_mutex_trylock。在來看下執行結果:

每當重複加鎖的時候都會發生加鎖失敗,但是不會發生死鎖。

下面來看下第二種情況:

**如下:

int value=0;

pthread_mutex_t mutex_value_tmp1=pthread_mutex_initializer;

pthread_mutex_t mutex_value_tmp2=pthread_mutex_initializer;

void read_data(){

printf("data=%d\n",value);

printf("end reading data\n");

void write_data(){

value+=1;

printf("data=%d\n",value);

printf("end writing data\n");

void threading_func1(){

int i=0;

int res=0;

pthread_t thread_id;

thread_id=pthread_self();

printf("thread id :%d\n",thread_id);

while(i++<4){

res=pthread_mutex_trylock(&mutex_value_tmp1);

if (res !=0){

printf("thread mutex1 failed\n");

read_data();

res=pthread_mutex_trylock(&mutex_value_tmp2);

if (res !=0){

printf("thread mutex2 failed\n");

res=pthread_mutex_unlock(&mutex_value_tmp2);

if (res !=0){

printf("mutex2 unlock failed\n");

res=pthread_mutex_unlock(&mutex_value_tmp1);

if (res !=0){

printf("mutex1 unlock failed\n");

sleep(2000);

pthread_exit((void *)2);

void threading_func2(){

int i=0;

int res=0;

pthread_t thread_id;

thread_id=pthread_self();

printf("thread id :%d\n",thread_id);

while(i++<4){

res=pthread_mutex_lock(&mutex_value_tmp2);

if (res !=0){

printf("thread mutex2 failed\n");

write_data();

res=pthread_mutex_lock(&mutex_value_tmp1);

if (res !=0){

printf("thread mutex1 failed\n");

res=pthread_mutex_unlock(&mutex_value_tmp1);

if (res !=0){

printf("mutex1 unlock failed\n");

res=pthread_mutex_unlock(&mutex_value_tmp2);

if (res !=0){

printf("mutex2 unlock failed\n");

sleep(2000);

pthread_exit((void *)2);

int main()

pthread_t tid1,tid2;

int res;

void *tret;

pthread_mutex_init(&mutex_value_tmp1,null);

pthread_mutex_init(&mutex_value_tmp2,null);

pthread_create(&tid1,null,threading_func1,null);

pthread_create(&tid2,null,threading_func2,null);

pthread_join(tid1,&tret);

printf("thread 1 exit code %ld\n",(long)tret);

pthread_join(tid2,&tret);

printf("thread 2 exit code %ld\n",(long)tret);

res=pthread_mutex_destroy(&mutex_value_tmp1);

if (res!=0){

printf("mutex can't be destroyed");

return 0;

執行結果如下:從下面的程式執行結果中可以看到,執行緒1鎖住了互斥量一,同時等待互斥量二;而執行緒2鎖住了互斥量二,同時等待互斥量一。這樣便造成了死鎖,進而引起了程式執行錯誤。在寫**的時候應該避免這類用法

java多執行緒 二 執行緒的互斥

多執行緒相對於單執行緒而言,大大的提高了硬體cpu的使用率,提高了處理的速度。任何事物帶來的都是兩面性的,多執行緒為我們帶來效能提高的同時也帶來了許多的安全性問題。說互斥之前,先說一下什麼是互斥,舉個列子,一天去atm機取錢,如果沒有互斥的話,你正取著錢突然有個人衝進來把你的錢搶走了。這時候你想,要...

執行緒 二 執行緒間共享資料 互斥鎖

一 互斥鎖的應用場景 什麼情況下使用 二 互斥鎖的幾種用法 include include include include include include include using namespace std class test void write private list int list ...

Linux多執行緒程式設計(二) 執行緒屬性

pthread介面允許我們通過設定每個物件關聯的不同屬性來細調執行緒的行為。include int pthread attr init pthread attr t attr int pthread attr destroy pthread attr t attr 兩個函式的返回值 若成功,返回0 ...