互斥鎖和條件變量是出自Posix線程標準,用來同步一個進程中各個線程的,同時也能夠用來同步幾個進程間的,不過這須要此互斥鎖和條件變量是存放在多個進程間共享的某個內存區的。函數
互斥鎖上鎖與解鎖:線程
#include <pthread.h> int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);
互斥鎖初始化的問題:
能夠經過兩種方式初始化一個互斥鎖變量:rest
1,若是互斥鎖變量是靜態分配的,那麼使用以下形式初始化:code
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;進程
2,若是互斥鎖是動態分配的,那麼我麼能夠用pthread_mutex_init函數初始化它。事件
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
這二者有個很關鍵的地方,靜態分配的話,只能使用默認的屬性,而對於動態分配的,咱們能夠設置屬性。
條件變量:等待與信號發送:內存
互斥鎖有個劣勢,那就是他僅僅是上鎖和解鎖,效率低,這時咱們能夠經過引入條件變量來解決問題,它容許一個線程或進程睡眠到某個事件爲止。get
#include <pthread.h> int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime); int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
#include <pthread.h> int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_signal(pthread_cond_t *cond);
2,把調用線程投入睡眠。同步
一旦這個函數被喚醒後,那麼在此函數返回前從新給互斥鎖上鎖。這也就決定了在接下來的程序裏必須有解鎖的步驟。it
互斥鎖和條件變量的屬性:
咱們能夠經過設置屬性來選擇是一個進程中多個線程同步仍是多個進程間的同步。
#include <pthread.h> int pthread_mutex_destroy(pthread_mutex_t *mutex); int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); int pthread_cond_destroy(pthread_cond_t *cond); int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
互斥鎖和條件變量的屬性如同互斥鎖和條件變量同樣,也分爲靜態和動態分配及其初始化。
#include <pthread.h> int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); int pthread_mutexattr_init(pthread_mutexattr_t *attr); int pthread_condattr_destroy(pthread_condattr_t *attr); int pthread_condattr_init(pthread_condattr_t *attr);
至於前面講到的更改互斥鎖和條件變量的屬性來達到切換是線程間同步仍是進程間同步的問題是經過以下函數來操做的:
#include <pthread.h> int pthread_mutexattr_getpshared(const pthread_mutexattr_t * restrict attr, int *restrict pshared); int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared); int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared); int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared);
pshared的值就是用來設置這個屬性的值,它能夠是PTHREAD_PROCESS_PRIVATE(線程間同步)或PTHREAD_PROCESS_SHARED(進程間同步)。
條件變量定時等待和廣播:
用來喚醒阻塞在此條件變量上的全部線程。
#include <pthread.h> int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime); int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
這裏要說明一點,對於第二個函數所提到的abstime,這是絕對時間,而不是咱們通常索說到的相差時間,也就是說這個時間是指自UTC時間以來所流逝的秒數和納秒數,這樣就有個一個好處:若是函數由於有信號到來而過早返回了,那麼這個函數能夠在無需更改參數的狀況下繼續再次被調用。
小結:
互斥鎖用於保護代碼臨界區,從而保證任什麼時候刻只有一個線程或者進程在臨界區執行。有時候一個線程得到某個互斥鎖後,發現本身須要等待某個條件變爲真,這樣線程就能夠等待在某個條件上。條件變量老是有一個互斥鎖與之關聯。
互斥鎖和條件變量能夠靜態分配並靜態初始化。它們也能夠動態分配並要求動態地初始化它們。動態初始化容許咱們指定進程間共享屬性,從而容許在不一樣進程間共享某個互斥鎖或條件變量,其前提是該互斥鎖或條件變量必須存在在由這些進程共享的內存區。