程序間通訊學習筆記-互斥鎖 && 讀寫鎖
第七章 互斥鎖和條件變數
互斥鎖是用於保護臨界區的,實際上是保護在臨界區中被操縱的資料,保護多個執行緒或者多個程序的共享資料。
#include<pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mptr);
int pthread_mutex_trylock(pthread_mutex_t *mptr);
int pthread_mutex_unlock(pthread_mutex_t *mptr);
如果互斥鎖已被其他執行緒佔據了,那麼pthread_mutex_lock將阻塞直到互斥鎖被解鎖。第二個函式在這種情況下,會返回一個EBUSY錯誤。
如果互斥鎖是靜態分配 的,可以用PTHREAD_MUTEX_INITIALIZER初始化為常量。如果互斥鎖是動態分配的,就要用pthread_mutex_init()函式初始化。
對比上鎖與等待
這個例子中,所有生產者執行緒都啟動後,立即啟動消費者執行緒。所以對消費者進行了改動,要判斷當前消費的i是否已經生產好了。每次對共享資料進行訪問時,都要申請互斥鎖。
條件變數:等待與訊號傳送
互斥鎖用於上鎖,條件變數用於等待
#include<pthread.h>
int pthread_cond_wait(pthread_cond_t *cptr,pthread_mutex_t *mptr );
int pthread_cond_signal(pthread_cond_t *cptr);
pthread_cond_wait等待某個條件為真時。這個函式原子地執行以下兩步:
- 給互斥鎖解鎖
- 把呼叫執行緒投入睡眠,知道另外其某個執行緒就本條件變數呼叫pthread_cond_signal函式
然後在這個函式返回前,對互斥鎖進行上鎖,修改共享資料,然後對互斥鎖進行解鎖
7.6 條件變數:定時等待和廣播、
單播和廣播,根據滿足條件後,要喚醒因為此條件而阻塞所有執行緒,還是一個等待執行緒而採用廣播和單播發送。
#include<pthread.h>
int pthread_cond_broadcast(pthread_cond_t *cptr );
int pthread_cond_timedwait(pthread_cond_t *cptr,pthread_mutex_t *mptr, const struct timespec *abstime);
pthread_cond_timedwait函式執行緒就阻塞時間設定一個限制值。如果發生超時,就返回ETIMEDOUT錯誤
時間值是絕對時間
7.7 互斥鎖和條件變數的屬性
#include<pthread.h>
int pthread_mutex_init(pthread_mutex_t *mptr, const pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mptr);
int pthread_cond_init(pthread_cond_t *cptr,pthread_condattr_t *attr);
int pthread_cond_destroy(pthread_cond_t *cptr);
互斥變數和條件變數用以上函式進行初始化和摧毀
#include<pthread.h>
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);
int pthread_condattr_destroy(pthread_condattr_t *attr);
以上函式是對互斥鎖、條件變數的屬性進行初始化和摧毀
第八章 讀寫鎖
讀寫鎖的分配規則:
- 沒有執行緒持有某個給定的讀寫鎖用於寫,就可以有任意數目的執行緒持有讀寫鎖用於讀
僅當沒有執行緒持有某個給定的讀寫鎖用於讀或用於學,才能分配這個讀寫鎖用於寫
這種對於給定資源的共享訪問稱為共享-獨佔上鎖。對於讀是共享鎖,對於寫是獨佔鎖
#include<pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_unlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_init(pthread_rwlock_t *rwptr,const pthread_rwlockattr_t *attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwptr);
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
執行緒取消
#include<pthread.h>
int pthread_cancel(pthraed_t pid);
void pthread_cleanup_push(void (*func)(void*),void *arg);
void pthread_cleanup_pop(int execute);
通過由對方呼叫函式pthread_cancel,一個執行緒可以被同一個程序內的任何其他執行緒所取消(cancel)
清理處理晨旭可以恢復任何需要恢復的狀態。push函式中func引數是呼叫執行緒被取消是所呼叫的函式的地址。pop函式是刪除呼叫執行緒的取消清理棧中位於在山頂的函式中的execute引數不為0時,就是呼叫這個函式、