1、一些基本概念
互斥:在同一時間內訪問資源的唯一性
同步:是一種時序性和協作性
臨界資源:一次僅允許乙個程序使用的資源
臨界區:訪問臨界資源的一段**
2、為什麼要進行同步?互斥?
執行緒互斥:因為多個執行緒是用共享乙個資源的,這個資源就是臨界資源,多個執行緒對資源的訪問就需要用到執行緒的同步和互斥。
執行緒同步:如果我們的某乙個執行緒優先順序特別高,那麼它可能一種佔據這個臨界資源,這個時候,其他執行緒也無法使用這個臨界資源,所以這個時候就需要我們使用同步了。程序同步的意思就是,每次使用完乙個資源後需要排隊。
3、如何同步?
*使用了條件變數或者訊號量保證同步。*
條件變數:
1)、概念:
條件變數就是等待某乙個條件的發生,和訊號一樣
2)、用法:
條件變數使我們睡眠的等待某種條件的發生
條件變數是利用執行緒間共享全域性變數進行同步的一種機制,主要包括兩種動作:
3)、建立
條件變數有兩種建立方式:
4)登出:
pthread_cond_destory(pthread_cont_t *cond)
使用條件:只有 在沒有 執行緒在該條件變數上等待的時候,才能 登出這個條件變數 ,否則返回ebusy。
5)等待條件變數:
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);//指定了乙個超過時間,在該時間內阻塞呼叫執行緒,並等待條件變數,如果在規定的時間內沒有發生,則該函式返回。
pthread_mutex_lock(&mutex)
while(條件為假)
pthread_cond_wait(cond,mutex);
修改條件
pthread_mutex_unlock(&mutex)
pthread_mutex_lock(&mutex)
設定條件為真
pthrea_cond_signal(cond);
pthread_mutex_unlock(&mutex);
8)、條件變數為什麼要和互斥鎖搭配使用
首先,條件變數的作用是等待某乙個條件的達成而處於掛起狀態,而這個條件通常是多個執行緒或者程序的共享變數,所以對這個共享變數很有可能發生了競爭尤其還對這個共享變數新增了條件限制,所以必須對這個共享變數加上互斥鎖。
訊號量:
posix訊號量和systemv訊號量作用相同,都用於同步操作,但是posix是用於執行緒間同步。
posix訊號量和systemv訊號量的區別:
1)函式區分: 對於所有system v訊號量函式,在它們的名字裡面沒有下劃線。例如,應該是semget()而不是sem_get()。然而,所有的的posix訊號量函式都有乙個下劃線。
2)system v的訊號量一般用於程序同步, 且是核心持續的, api為
semget
semctl
semop
posix的有名訊號量一般用於程序同步, 有名訊號量是核心持續的. 有名訊號量的api為
sem_open
sem_close
sem_unlink
posix的無名訊號量一般用於執行緒同步, 無名訊號量是程序持續的, 無名訊號量的api為
sem_init
sem_destroy
posix訊號量:
1)、初始化訊號量:
int sem_init(sem_t *sem, int pshared, unsigned int value);
引數: 引數value 為訊號量的初始值。引數pshared用於說明訊號量的共享範圍,如果pshared 為0,那麼該訊號量只能由初始化這個訊號量的程序中的執行緒使用,如果pshared 非零,任何可以訪問到這個訊號量的程序都可以使用這個訊號量
返回值 :0表示成功,其他表示失敗。
2)、等待訊號量
int sem_wait(sem_t *sem);
3)、發布訊號量
int sem_post(sem_t *sem);
4)、訊號量銷毀
int sem_destory(sem_t *sem);
用posix訊號量實現執行緒間同步,生產者消費者問題
分析:先給消費者訊號量初始值置1,當消費者消費了以後發布訊號給生產者讓其生產,生產者接受這個訊息後生產者開始生產,生產完畢後發布訊息給消費者。
4、如何互斥?
使用互斥鎖達到互斥的效果:
在使用互斥鎖之前需要定義互斥鎖(全域性變數),定義形式如下:
pthread_mutex_t lock;
(1)、互斥鎖的初始化
在pthread_mutex_init()函式中:
1)、int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
- 引數:
mutex:是指向要初始化的互斥量的指標(全域性變數)
attr:是指向屬性物件的指標,一般使用null
2)可以通過巨集pthread_mutex_initializer來初始化靜態分配的互斥鎖 :
pthread_mutex_t mutex=pthread_mutex_initializer
對於靜態初始化的互斥鎖,不需要呼叫pthread_mutex_init函式。
(2)、互斥鎖的銷毀
int pthread_mutex_destroy(pthread_mutex_t *mutex);
(3)、鎖的操作
int pthread_mutex_lock(pthread_mutex_t *mutex);//加鎖操作,如果獲取不到資源就處於掛起狀態(阻塞的)
int pthread_mutex_trylock(pthread_mutex_t *mutex);//獲取不到鎖資源,立即報錯 (非阻塞的)
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout);
int pthread_mutex_unlock(pthread_mutex_t *mutex);//解鎖操作
通常是以下過程:
1)、初始化互斥鎖
2)、加鎖(申請)
3)、對臨界資源的操作
4)、解鎖(在任何可能退出的地方都要有解鎖操作)
(4)、死鎖問題
死鎖主要發生在有多個依賴鎖形成時,如何避免死鎖時使用互斥量要格外注意的東西。
造成死鎖的四個必要條件:
(5)、避免死鎖:
執行緒同步和互斥的區別
互斥是指某一資源同時只允許乙個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。同步是指在互斥的基礎上 大多數情況 通過其它機制實現訪問者對資源的有序訪問。同步其實已經實現了互斥,所以同步是一種更為複雜的互斥。互斥是一種特殊的同步。所謂互斥,就是不同執行緒...
執行緒同步和互斥的區別
互斥是指某一資源同時只允許乙個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。同步是指在互斥的基礎上 大多數情況 通過其它機制實現訪問者對資源的有序訪問。同步其實已經實現了互斥,所以同步是一種更為複雜的互斥。互斥是一種特殊的同步。所謂互斥,就是不同執行緒...
windows多執行緒互斥和同步
位址二 win 多執行緒 define thread num 10 int threadcount 0 int threadno 0 用於互斥 critical section nocritical critical section countcritical handle nomutexhandl...