執行緒的同步與互斥

2021-08-19 11:04:24 字數 3508 閱讀 4711

情況:大多數執行緒試圖修改臨界資源,這時就可以申請鎖,保證臨界資源的安全性。

mutex(互斥量)

如果多個執行緒一同操作共享變數,會造成一些問題。

乙個售票系統,多個執行緒一起進行購票操作。

#include#include#include#includeint ticket = 100;

void *route(void* arg)

else

}}int main()

這裡可以寫乙個迴圈來建立和等待,

thread 1 sells tickets: 100

thread 2 sells tickets: 99

thread 3 sells tickets: 98

thread 4 sells tickets: 97

thread 1 sells tickets: 96

thread 2 sells tickets: 95

...thread 4 sells tickets: 4

thread 1 sells tickets: 3

thread 2 sells tickets: 2

thread 3 sells tickets: 1

thread 4 sells tickets: 0

thread 1 sells tickets: -1

thread 2 sells tickets: -2

這裡結果發現就出現了問題。

這裡提乙個概念,原子操作(不會被執行緒排程機制打斷的操作,操作一旦開始,一直執行結束)。

這個**中--ticket操作本身就不是乙個原子的操作。

呼叫反彙編來看的話--操作對應著3條彙編指令。

問題來了,那這種問題該怎麼解決?

1.**必須要有互斥行為,當**進入臨界區執行時,其他執行緒不允許進入臨界區。

2.若臨界區沒有執行緒在執行,且多個執行緒想執行臨界區的**,那麼,只允許進入乙個執行緒進入。

3。該執行緒不在臨界區執行**,那麼也不能阻止其他執行緒進入臨界區。

互斥量的介面

初始化互斥量

動態分配:    

#include int pthread_mutex_destroy(pthread_mutex_t *mutex);

int pthread_mutex_init(pthread_mutex_t *restrict mutex,

const pthread_mutexattr_t *restrict attr);

靜態分配:

pthread_mutex_t mutex = pthread_mutex_initializer;
銷毀互斥量

注意;1.屬於靜態分配初始化的互斥量不需要銷毀

2.不要銷毀乙個已經加鎖的互斥量

3.已經銷毀的互斥量,要確保後面不會有執行緒再嘗試加鎖。

#include int pthread_mutex_destroy(pthread_mutex_t *mutex);
互斥量的加鎖和解鎖:

#include int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

在呼叫lock時,會出現以下情況:

1.互斥量處於未鎖狀態,此時函式會將互斥量鎖定,返回成功

2.發起函式呼叫時,其他執行緒已經鎖定互斥量,或者其他執行緒同時申請互斥量,但沒有競爭到互斥量,此時pthread_lock將會陷入阻塞狀態,等待互斥量解鎖。

改進以上售票系統:

int ticket = 100;

pthread_mutex_t mutex;

void *route(void* arg)

else

}}

...

thread 1 sells tickets: 5

thread 1 sells tickets: 4

thread 1 sells tickets: 3

thread 1 sells tickets: 2

thread 1 sells tickets: 1

臨界資源狀態

實現多個執行緒之間的同步

當乙個互斥的訪問某個變數時,在其他執行緒改變狀態之前,什麼也做不了。

條件變數的介面:

#include int pthread_cond_destroy(pthread_cond_t *cond);

int pthread_cond_init(pthread_cond_t *restrict cond,

const pthread_condattr_t *restrict attr);//cond 要初始化的條件變數

pthread_cond_t cond = pthread_cond_initializer;

等待條件滿足:

int pthread_cond_wait(pthread_cond_t *restrict cond,

pthread_mutex_t *restrict mutex);

//cond在這個條件變數上等待,mutex:必須要有乙個互斥鎖與他配合使用
第乙個引數:在該條件下等待,釋放鎖,

第二個引數:重新獲得鎖,並等待執行

喚醒等待:

int pthread_cond_broadcast(pthread_cond_t *cond);//喚醒大量執行緒

int pthread_cond_signal(pthread_cond_t *cond);//喚醒單個執行緒

#include#include#include#includepthread_cond_t cond;

pthread_mutex_t mutex;

void *run1(void* arg)

}void* run2(void* arg)

}int main()

[root@localhost cond]# gcc cond.c -lpthread

[root@localhost cond]# ./a.out

world

world

world

^c

如果將注釋去掉

[root@localhost cond]# gcc cond.c -lpthread

[root@localhost cond]# ./a.out

world

world

hello

hello

world

hello

^c

執行緒同步與互斥

與多程序互動一樣,各個不同的執行緒之間也會存在資源的共享問題。為了解決多執行緒之間對資源訪問的同步和互斥問題,我們需要了解執行緒同步機制。第一種機制 互斥鎖 互斥鎖是一種簡單的加鎖方法,可以使單個執行緒進行對資源訪問的原子操作。互斥鎖的基本操作就是加鎖和解鎖。互斥鎖主要包含以下函式 1 初始化函式 ...

執行緒同步與互斥

1.執行緒互斥 執行緒互斥是指某一資源同時只允許乙個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。同步就是協同步調,按預定的先後次序進行執行。如 你說完,我再說。同 字從字面上容易理解為一起動作 其實不是,同 字應是指協同 協助 互相配合。如程序 執行...

執行緒的同步與互斥

進行多執行緒程式設計,因為無法知道哪個執行緒會在哪個時候對共享資源進行操作,因此讓如何保護共享資源變得複雜,通過下面這些技術的使用,可以解決 執行緒之間對資源的競爭 1.互斥量mutex 2.訊號燈semaphore 3.條件變數 conditions mutex 互斥鎖線程控制 1 互斥鎖是用一種...