#include
//靜態初始化乙個mutex型別的變數
pthread_mutex_t fastmutex = pthread_mutex_initializer;
int pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *mutexattr);
功能: 使用預設的屬性初始化mutex鎖.
引數:mutex 指定要初始化的mutex鎖
mutexattr null 使用預設的屬性初始化mutex鎖
返回值:
總是返回0
int pthread_mutex_lock(pthread_mutex_t *mutex);
功能: 如果mutex鎖目前是unlocked狀態,當前執行緒鎖定這把鎖,立即返回,如果mutex鎖已經被其他執行緒鎖定,當前執行緒掛起直到鎖被解除
引數:mutex 指定要操作的mutex鎖
返回值:
成功 0
錯誤 非0的錯誤碼
int pthread_mutex_trylock(pthread_mutex_t *mutex);
功能:如果unlocked,立即上鎖,否則,返回error code ebusy
引數:mutex
返回值:
成功 0
錯誤 非0的錯誤碼
int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:解鎖 解除的鎖一定是被當前執行緒占有的 並且被鎖定的
引數:mutex 指定要解除的鎖
返回值:
成功 0
錯誤 非0的錯誤碼
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能: 銷毀mutex鎖 釋放資源
引數:mutex 指定要被銷毀的mutex鎖
返回值:
成功 0
錯誤 非0的錯誤碼
mutex.c
#include
#include
int v =0;
//靜態初始化mutex鎖,也可以呼叫pthread_mutex_init()
pthread_mutex_t mut = pthread_mutex_initializer;
void
*handle
(void
*arg)
return
null;}
intmain
(void
)
執行結果:
執行分析:如果不加mutex鎖的情況下,開兩個執行緒執行handle方法,由於兩個執行緒共享全域性變數v,所以tmp不會打到2000,加了鎖之後,同一時刻只有乙個執行緒可以訪問全域性變數v,所以tmp最終會到2000.
鎖只能保證同一時刻只有乙個執行緒訪問公共資源,但並不能很好的協調兩個執行緒工作。比如,如果實現生產者消費者模型,將v作為公共資源,生產者執行緒使v增加,消費者執行緒使v減少,當v為0時消費者不能消費。在實現這個模型時,如果只是用mutex鎖實現,相當於兩個執行緒無論在什麼情況下,都會是公平的競爭公共資源,但有時我們並不希望這樣。比如,當v為0時,我們不希望消費者執行緒再占用cpu資源,直接讓生產者控制全域性變數v就好,但是mutex會公平地讓兩個執行緒競爭。如果消費者執行緒競爭勝利,那麼由於v=0,消費者只是if(v=0) do nothing 的語句執行一下,白白占用cpu,而實際情況我們更希望在這種情況下,直接讓消費者讓出cpu,直接讓生產者控制,直至v>0時,兩個執行緒再公平競爭。這時,就需要用到條件變數。
pthread_cond_t 條件變數型別
//靜態初始化乙個條件變數pthread_cond_t cond = pthread_cond_initializer;
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
功能: 使用預設屬性初始化條件變數
引數:cond 指定要初始化的條件變數
cond_attr null 使用預設的屬性
返回值:成功返回0,失敗返回errno
int pthread_cond_signal(pthread_cond_t *cond);
功能:從等著條件變為真的執行緒中取出乙個重新執行.如果沒有執行緒等待條件變為真那麼什麼都不發生.
引數:cond 指定條件變數 等著這個條件變為真
返回值:成功返回0,失敗返回errno
int pthread_cond_broadcast(pthread_cond_t *cond);
功能:重新啟動所有等待條件為真的執行緒.如果沒有執行緒等待條件為真,什麼都不做
引數:cond 指定具體的條件變數 等著這個條件變為真
返回值:成功返回0,失敗返回errno
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
功能:解鎖(使用這個函式之前,一定加鎖),掛起等待cond is signaled,直到cond is signaled該函式返回,返回之前重新獲得鎖(重新上鎖)
引數:cond 指定要操作的條件變數
mutex 使用到的mutex鎖
返回值:成功返回0,失敗返回errno
該函式通常配合while語句使用,當while條件滿足時,則呼叫該函式阻塞,當其他執行緒完成某項工作,使while條件滿足了,就呼叫signal函式,wait函式返回並重新獲得鎖,回到while迴圈,由於此時條件不滿足,則不在進入迴圈呼叫wait,執行迴圈之後的語句
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
功能:帶計時的wait
int pthread_cond_destroy(pthread_cond_t *cond);
功能:銷毀條件變數
引數:cond 指定要銷毀的條件變數
返回值:
成功 0
錯誤 非0
用條件變數實現上述生產者消費者模型(不對生產者限制,只限制消費者,只有有貨物時才可以消費)
cond.c
#include
#include
#include
#include
#include
//定義節點型別
typedef
struct nodenode_t;
node_t *head =
null
;//定義乙個空鍊錶
pthread_mutex_t mutex;
//定義乙個鎖
pthread_cond_t cond;
//定義乙個條件變數
//生產者執行緒
void
*p_func
(void
*arg)
return
null;}
//消費者執行緒
void
*c_func
(void
*arg)
//從鍊錶的頭部摘取乙個節點
tmp = head;
head = head->next;
//解鎖
pthread_mutex_unlock
(&mutex)
;//消費摘取的節點
printf
("c:%d\n"
, tmp->data)
;free
(tmp)
; tmp =
null
;//休眠1~4秒
sleep
(rand()
%4+1
);}return0;
}int
main
(void
)
用訊號和自定義訊號處理函式及pause函式模擬用條件變數實現的生產者消費者模型:只是模擬,方便深入理解條件變數的過程,很多細節肯定是條件變數更優。int v作為公共變數,生產者使它增加,消費者使它減少.
#include
#include
#include
#include
#include
#include
#include
void
my_block
(int n)
int v =0;
//靜態初始化mutex鎖,也可以呼叫pthread_mutex_init()
pthread_mutex_t mut = pthread_mutex_initializer;
void
*producer
(void
*arg)
}void
*consumer
(void
*arg)
else
pthread_mutex_unlock
(&mut)
;sleep
(rand()
%3+1
);}}
intmain
(void
)
執行緒同步之mutex篇
原理 當乙個互斥物件不再被乙個執行緒所擁有,它就處於發訊號狀態。此時首先呼叫waitforsingleobject 函式的執行緒就成為該互斥物件的擁有者,此互斥物件設為不發訊號狀態。當執行緒呼叫releasemutex 函式並傳遞乙個互斥物件的控制代碼作為引數時,這種擁有關係就被解除,互斥物件重新進...
執行緒同步之互斥量Mutex
前面的文章介紹了執行緒的建立 終止 連線和分離。本篇介紹執行緒的同步。多執行緒的難點是對共享資源的訪問,如何保證多個執行緒能夠 同時 訪問同乙個共享資源而又不引起衝突,就是執行緒同步的本質。互斥量用來確保共享資源同時只被乙個執行緒訪問。互斥量有兩種狀態 已鎖定 locked 和未鎖定 unlocke...
C 多執行緒同步 二 Mutex
monitor和lock多用於鎖定被呼叫端,而mutex則多用鎖定呼叫端。lock this 或者是用monitor也是一樣的,如下 monitor.enter this do something monitor.exit this monitor的好處是可以用tryenter this,timeo...