目錄
POSIX信號量
int sem_destroy(sem_t* sem);
?int sem_wait(sem_t* sem);
?int sem_post(sem_t* sem);
互斥量
條件變量
為了對多線程程序實現同步問題,可以用信號量POSIX信號量、互斥量、條件變量進行線程同步,以達到對共享資源的最大利用。
POSIX信號量
POSIX信號量由sem_ 開頭,主要有五個信號量函數。
int sem_init(sem_t* sem,int pshared,unsingned int value);
pshared參數指定信號量的類型,如果為0則代表這個信號量是這個線程局部信號量,否則該信號量就會在多個線程之間共享。
value參數指定信號量的初始值。
不能初始化一個已經被初始化的信號量!!!
int sem_destroy(sem_t* sem);
用于銷毀信號量,釋放其占用的內核資源
?int sem_wait(sem_t* sem);
以原子操作的方式將信號量的值減1,如果信號量為0則被阻塞,知道該信號量具有非0值
?int sem_post(sem_t* sem);
//以原子操作方式將信號量加一,信號量大于0時,喚醒調用sem_post的線程
#include<semaphore.h>//用于初始化一個未命名的信號量
int sem_init(sem_t* sem,int pshared,unsingned int value);//用于銷毀信號量
int sem_destroy(sem_t* sem);//用以原子操作方式將信號量減一,信號量為0時,sem_wait阻塞
int sem_wait(sem_t* sem);//相當于sem_wait的非阻塞版本,直接立即返回信號量,無論其是否為0
int sem_trywait(sem_t* sem);//以原子操作方式將信號量加一,信號量大于0時,喚醒調用sem_post的線程
int sem_post(sem_t* sem);
class sem
{
public:sem(){if (sem_init(&m_sem, 0, 0) != 0){throw std::exception();}}sem(int num){if (sem_init(&m_sem, 0, num) != 0){throw std::exception();}}~sem(){sem_destroy(&m_sem);}bool wait(){return sem_wait(&m_sem) == 0;}bool post(){return sem_post(&m_sem) == 0;}private:sem_t m_sem;
};
互斥量
互斥鎖,也成互斥量,可以保護關鍵代碼段,以確保獨占式訪問.當進入關鍵代碼段,獲得互斥鎖將其加鎖;離開關鍵代碼段,喚醒等待該互斥鎖的線程.
#include<pthread.h>//用于初始化互斥鎖
int pthread_mutex_init(pthread_mutex_t* mutex,const pthread_mutexattr* mutexattr);//用于銷毀互斥鎖
int pthread_mutex_destroy(pthread_mutex* mutex);//以原子操作方式給互斥鎖加鎖
int pthread_mutex_lock(pthread_mutex_t* mutex);//以原子操作方式給互斥鎖解鎖
int pthread_mutex_unlock(pthread_mutex_t* mutex);
class locker
{
public:locker(){if (pthread_mutex_init(&m_mutex, NULL) != 0){throw std::exception();}}~locker(){pthread_mutex_destroy(&m_mutex);}bool lock(){return pthread_mutex_lock(&m_mutex) == 0;}bool unlock(){return pthread_mutex_unlock(&m_mutex) == 0;}pthread_mutex_t *get(){return &m_mutex;}private:pthread_mutex_t m_mutex;
};
條件變量
條件變量提供了一種線程間的通知機制,當某個共享數據達到某個值時,喚醒等待這個共享數據的線程.
#include<pthread.h>//用于初始化條件變量
int pthread_cond_init(pthread_cond_t* cond,const pthread_condatte_t* cond_attr);//用于銷毀條件變量
int pthread_cond_destroy(pthread_cond_t* cond);//以廣播的方式喚醒所有等待目標條件變量的線程
int pthread_cond_broadcast(pthread_cond_t* cond)/*用于等待目標條件變量.該函數調用時需要傳入 mutex參數(加鎖的互斥鎖) ,函數執行時,先把調用線程放入條件變量的請求隊列,然后將互斥鎖mutex解鎖,當函數成功返回為0時,互斥鎖會再次被鎖上. 也就是說函數內部會有一次解鎖和加鎖操作.*/
int pthread_cond_signal(pthread_cond_t* cond);//用于等待目標條件變量,mutex參數是用于保護條件變量的互斥鎖
int pthread_cond_wait(pthread_cond_t* cond,pthread_mutex_t* mutex);
class cond
{
public:cond(){if (pthread_cond_init(&m_cond, NULL) != 0){//pthread_mutex_destroy(&m_mutex);throw std::exception();}}~cond(){pthread_cond_destroy(&m_cond);}bool wait(pthread_mutex_t *m_mutex){int ret = 0;//pthread_mutex_lock(&m_mutex);ret = pthread_cond_wait(&m_cond, m_mutex);//pthread_mutex_unlock(&m_mutex);return ret == 0;}bool timewait(pthread_mutex_t *m_mutex, struct timespec t){int ret = 0;//pthread_mutex_lock(&m_mutex);ret = pthread_cond_timedwait(&m_cond, m_mutex, &t);//pthread_mutex_unlock(&m_mutex);return ret == 0;}bool signal(){return pthread_cond_signal(&m_cond) == 0;}bool broadcast(){return pthread_cond_broadcast(&m_cond) == 0;}private://static pthread_mutex_t m_mutex;pthread_cond_t m_cond;
};