==關於死鎖==
條件訊號(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...