執行緒學習之互斥鎖

2021-10-11 05:15:25 字數 4011 閱讀 1775

==關於死鎖==

條件訊號(conditional)

1.相關api

具體例子:

==程式設計遇到的問題==:

當乙個程序中存在兩個及以上(乙個程序本來就有乙個執行緒)的執行緒時,執行緒間會互相爭奪共享資源,導致單個執行緒中的執行秩序會被打亂。所以需要用到互斥量來進行秩序控制,保證單個執行緒中的程式先執行完畢。

所以互斥鎖的作用就是使上鎖與解鎖之間的**完整的、不受別的執行緒「打擾」的執行完。而另乙個執行緒必須等到這個鎖解開了,才能執行自己的**。注意互斥鎖不能控制多執行緒的執行順序,也就是我們加了鎖之後,並不知道先執行那個執行緒.

函式原型; int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

引數說明:

1. *mutex:互斥量的索引(名稱),為指標變數;

2. *attr:互斥量的屬性,通常為 null。

返回值: 成功返回0;失敗返回錯誤編碼。

我們在使用的時候,應該把 *mutex定義為全域性變數,這樣所有的執行緒都能使用。

函式原型; int pthread_mutex_destroy(pthread_mutex_t *mutex);

引數說明:

*mutex:互斥鎖的索引(名稱),注意這裡同樣是指標變數。

返回值: 成功返回0;失敗返回錯誤編碼;

我們在所有執行緒都執行完畢後,應該銷毀互斥鎖。

用法:

#include

pthread_mutex_t mutex;

//定義互斥鎖的索引

intmain()

函式原型; int pthread_mutex_lock(pthread_mutex_t *mutex);

引數說明:

*mutex: 互斥鎖的索引(名稱),注意這裡同樣是指標變數。

返回值: 成功返回0;失敗返回錯誤編碼;

用法結合解鎖函式pthread_mutex_unlock來介紹。

函式原型; int pthread_mutex_unlock(pthread_mutex_t *mutex);

引數說明:

*mutex:互斥鎖的索引(名稱),注意這裡同樣是指標變數。

返回值: 成功返回0;失敗返回錯誤編碼;

用法結合上鎖函式pthread_mutex_lock來介紹。

例子:

void

fun1

(void

*s)pthread_mutex_unlock

(&mutex)

;//解鎖

pthread_exit

(null);

}

兩個子執行緒使用不同的互斥鎖,當它們在各自還沒有釋放鎖的(pthread_mutex_unlock)時候,獲取對方的鎖,導致程式一直卡在pthread_mutex_lock 處,這種情況就是死鎖。我們程式設計的時候,因為**量大,可能不經意間就出現死鎖。(即在未解鎖的情況下兩次獲取同一把鎖(pthread_mutex_lock),第二次lock鎖的時候會阻塞。)

**在程序裡,如果沒有條件訊號去控制線程的話,我們無法確定程序會先執行哪個執行緒,但是使用條件訊號的話,我們可以去控制線程的執行順序。

條件本身是由互斥量保護的。執行緒在改變條件狀態前必須首先鎖住互斥量,其他執行緒在獲得互斥量之前不會察覺到這種改變,因為必須鎖定互斥量以後才能計算條件。

條件變數使用之前必須首先初始化,pthread_cond_t資料型別代表的條件變數可以用兩種方式進行初始化,可以把常量pthread_cond_initializer賦給靜態分配的條件變數。

函式原型; int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);

引數說明:

1. *cond :條件訊號的索引(名稱),為指標變數;

2. *attr :條件的屬性,通常為 null。

返回值: 成功返回0;失敗返回錯誤編碼。

我們在使用的時候,應該把 *cond定義為全域性變數,這樣所有的執行緒都能使用。

用法:

#include

pthread_cond_t cond;

//定義條件訊號的索引

intmain()

函式原型; int pthread_cond_destroy(pthread_cond_t *cond);

引數說明:

*cond :條件訊號的索引(名稱),為指標變數;

返回值: 成功返回0;失敗返回錯誤編碼。

另外在所有執行緒都是執行完畢後,也需要把條件訊號銷毀。

用法:#include

pthread_cond_t cond;//定義條件訊號的索引

int

main()

1

函式原型; int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t * mutex);

引數說明:

1. *cond :條件訊號的索引(名稱),為指標變數,需要等待條件訊號;

2. *mutex :為互斥鎖,在mutex這個鎖裡等待條件訊號。

返回值: 成功返回0;失敗返回錯誤編碼。

用法: 配合條件訊號傳送函式pthread_cond_signal(觸發方式,也叫點播方式)來介紹。

函式原型; int pthread_cond_signal(pthread_cond_t *restrict cond);

引數說明:

*cond :條件訊號的索引(名稱),為指標變數,需要傳送的條件訊號;

返回值: 成功返回0;失敗返回錯誤編碼。

用法: 配合條件訊號傳送函式pthread_cond_wait(觸發方式,也叫點播方式)來介紹。

#include

pthread_cond_t cond;

//定義條件訊號的索引

pthread_mutex_t mutex;

//定義互斥鎖的索引

void

*t1_t(void

* arg)

void

*t2_t(void

* arg)

intmain()

現象:程式執行後執行完main函式和fun1函式後就沒反應了。。

原因:由於在條件語句外沒寫使data++的語句,滿足不了(data3)的條件;使pthread_cond_signal()執行不了。使程式阻塞了。

#include

#include

#include

int data=0;

int i;

pthread_cond_t cond=pthread_cond_initializer;

//靜態初始化

pthread_mutex_t mutex=pthread_mutex_initializer;

void

fun1

(void

*s)printf

("fun1:%d\n"

,data++);

//讓data++使之達到3

}pthread_exit

(null);

}void

fun2

(void

*s)}

intmain()

補充

將執行結果輸入到txt檔案中

a.out中**:

#include

intmain

(int argc,

char

**ar**)

return0;

}

執行緒同步之互斥鎖

為什麼要執行緒同步?當多執行緒共享相同的記憶體的時候,需要每乙個執行緒看到相同的檢視。當乙個執行緒被修改時,其他的執行緒也可以修改或者讀取這個變數,所以就需要對這些執行緒同步,保證不會訪問到無效的變數。舉個例子 由此可見,執行緒同步的重要性。執行緒同步之互斥鎖的函式 1.include 2.int ...

執行緒 互斥鎖

include include include include include 1.靜態初始化,當動態初始化時,遮蔽靜態初始化 pthread mutex t mutex pthread mutex initializer 2.動態初始化 pthread mutex t mutex int lock...

執行緒互斥鎖

執行緒互斥鎖 降低效率,保證資料安全 執行緒 資料共享 修改共享資料,資料不安全 from threading import thread,lock import time n 100 deftask global n temp n time.sleep 0.1 n temp 1 if name m...