Linux多執行緒程式設計 執行緒的同步

2022-09-15 07:48:08 字數 4082 閱讀 7545

posix訊號量

posix訊號量不同於ipc中的訊號量 

常用的posix訊號量函式

#include

int sem_init(sem_t* sem,int pshared,unsigned int value);

//初始化乙個訊號量,pshared引數指定訊號量的型別,若為0,表示訊號量為當前程序的區域性訊號量,否則,該訊號量就可以在多個程序之間共享。value引數指定訊號量的初始值。

int sem_destroy(sem_t* sem);

//銷毀乙個訊號量,釋放它所占有的核心資源

int sem_wait(sem_t* sem);

//讓訊號量的值減一,如果訊號量的值為0,則阻塞,直到訊號量的值為非0.

int sem_trywait(sem_t* sem);

//sem_wait的非阻塞版本,若訊號量的值為0,返回乙個錯誤值 -1,並設定errno為eagain.

int sem_post(sem_t* sem);

//讓訊號量的值加1,當訊號量的值大於0時,其他正在呼叫sem_wait的函式將被喚醒。

上面這寫函式成功返回0,失敗返回-1.

互斥鎖

互斥量相當與鎖,在使用共享資源時,對它加鎖,使用完後,釋放鎖,在加鎖期間,其他的執行緒不能對該共享資源進行操作.

資料型別:pthread_mutex_t

相關api

初始化和銷毀互斥量

初始化乙個互斥量時也可以賦值為pthread_mutex_initializer

int pthread_mutex_init(pthread_mutext_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

//attr設定為null,代表以預設屬性初始化互斥量

int pthread_mutex_destroy(pthread_mutex_t *mutex);

加鎖

int pthread_mutex_lock(pthread_mutex_t *mutex);

//對互斥量加鎖,若互斥量已加鎖,則會阻塞,直到訊號量解鎖,成功返回0,

int pthread_mutex_trylock(pthread_mutex_t *mutex);

//如果訊號量沒被鎖,則加鎖,並返回0,若訊號已被鎖,則不會阻塞,返回乙個非0值

int pthread_mutex_unlock(pthread_mutex_t *mutex);

int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,const struct timespec *restrict tsptr);

//當執行緒試圖獲取乙個已經加鎖的互斥量時,該函式可以設定等待時間,若在該時間內,互斥量被解鎖,則呼叫該函式的執行緒可以繼續執行,若沒有解鎖,則該函式不會對互斥量加鎖,而是返回乙個錯誤**etimedout,成功返回0

#include #include 

struct

foo;

struct foo* foo_alloc(int

id) }

return

(fp);

}void foo_hold(struct foo *fp)

void foo_rele(struct foo *fp)

else

}

讀寫鎖

讀寫鎖有三種狀態,加讀鎖,加寫鎖,不加鎖,當位於寫鎖時,所有企圖對讀寫鎖加鎖(無論時加讀鎖還是寫鎖)的執行緒都會阻塞,當位於加讀鎖時,所有試圖對其加讀鎖的執行緒可以繼續執行,但是加寫鎖的執行緒會阻塞。當讀寫鎖位於讀狀態時,如果有一線程試圖對其加寫鎖,那麼讀寫鎖通常會阻塞隨後的加讀鎖請求,這樣可以避免讀模式鎖長期占用,而寫模式鎖請求得不到滿足。

資料型別  pthread_rwlock_t

#include

int pthread_rwclock_init(pthread_rwlock_t *restrict rwlock,const pthread_relockattr_t *restrict attr);   //初始化乙個讀寫鎖,要先分配記憶體。

int pthread_rwclock_destroy(pthread_rwlock_t *rwlock)    //銷毀鎖   。2個函式成功返回0

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);   //加讀鎖

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); //加寫鎖

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); //解鎖 若成功都返回0

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);  //成功返回0

條件變數

如果說互斥鎖用於同步執行緒對共享資料的訪問,那麼條件變數就是用於同步共享資料的值。

#include

int pthread_cond_init(pthread_cond_t* cond,pthread_condattr_t* cond_attr);

初始化乙個條件量,若cond_attr為null,則以預設熟悉初始化,還可以pthread_cond_t cond=pthread_cond_initializer;

int pthread_cond_destroy(pthread_cond_t* cond);

int pthread_cond_signal(pthread_cond_t* cond);

喚醒乙個等待該條件變數的執行緒

int pthread_cond_broadcast(pthread_cond_t* cond);

喚醒所有等待該條件變數的執行緒

int pthread_cond_wait(pthread_cond_t* cond,pthread_mutex_t* mutex);

等待目標條件變數,mutex用來保證該函式操作的原子性,在使用pthread_cond_wait函式之前,需保證對mutex加鎖。該函式執行時,把呼叫執行緒加入條件變數的等待佇列。呼叫完後需要對mutex解鎖。

上面的函式成功返回0,失敗返回錯誤**。

下面是乙個執行緒同步機制的包裝類

#include #include 

#include

class

sem }

~sem()

//equal p operation

bool

wait()

//equal v operation

bool

post()

private

: sem_t m_sem;

};class

locker

}~locker()

bool

lock

()

bool

unlock()

private

: pthread_mutex_t m_mutex;

};class

cond

if(pthread_cond_init(&m_cond,null)!=0

) }

~cond()

bool

wait()

bool

signal()

private

: pthread_mutex_t m_mutex;

pthread_cond_t m_cond;

};

Linux多執行緒程式設計(2)執行緒同步

執行緒同步 a.mutex 互斥量 多個執行緒同時訪問共享資料時可能會衝突,這跟前面講訊號時所說的可重要性是同樣的問 題。假如 兩個執行緒都要把某個全域性變數增加1,這個操作在某平台需要三條指令完成 1.從記憶體讀變數值到暫存器 2.暫存器的值加1 3.將暫存器的值寫回記憶體 我們通過乙個簡單的程式...

多執行緒程式設計 執行緒同步

同步,永遠是多執行緒程式設計中最核心和最重要的話題.同步相關的概念比如 臨界區,原子操作,以及互斥量等等 總的來說,在多個執行緒之間採取同步措施,無非是為了讓他們更好的協同工作或者維持共享資料的一致性.1.共享資料的一致性 實際上,保證共享資料一致性的最簡單且最好的方法,就是使得該資料成為乙個常量,...

Linux多執行緒,執行緒同步

5 執行緒私有資料 程序內的所有執行緒共享程序的資料空間,因此全域性變數為所有執行緒所共有。但有時執行緒也需要儲存自己的私有資料,這時可以建立執行緒私有資料 thread specific date tsd 來解決。例如我們常見的變數 errno 它返回標準的出錯資訊。它顯然不能是乙個區域性變數,幾...