Linux執行緒同步之 條件變數

2021-07-30 03:04:51 字數 3975 閱讀 5629

條件變數是執行緒可用的另一種同步機制。條件變數給多執行緒提供了乙個會合的場所。它主要包括兩個動作:乙個執行緒等待「條件變數的條件成立」而掛起;另乙個執行緒使「條件成立」(給出條件成立訊號)。條件變數與互斥量一起使用時,允許執行緒以無競爭的方式等待特定的條件發生。

條件變數本身是互斥量保護的。執行緒在改變條件狀態之前必須首先鎖住互斥量。其他執行緒在獲得互斥量之前不會覺察到這種改變,因為互斥量必須在鎖定以後才能計算條件。

在使用條件變數之前,必須對它進行初始化。由pthread_cond_t資料型別表示的條件變數可以用兩種方式進行初始化,可以把常量pthread_cond_initializer賦給靜態分配的條件變數,但是如果條件變數是動態分配的,則需要使用pthread_cond_init函式對它進行初始化。

在釋放條件變數底層的記憶體空間之前,可以使用pthread_cond_destroy函式對條件變數進行反初始化。

#include int pthread_cond_init(pthread_cond_t *restrict cond,

const pthread_condattr_t *restrict attr);

int pthread_cond_destroy(pthread_cond_t *cond);

兩個函式的返回值:若成功,返回0;否則,返回錯誤編號

通常情況下,pthread_cond_init函式的attr引數設定為null。

我們使用pthread_cond_wait等待條件變數變為真。pthread_cond_wait函式與pthread_cond_wait函式相似,只是多了乙個超時。超時值指定我們願意等待多長的時間,它通過timespace結構指定,這個時間值是乙個絕對數而不是相對數。如果超時到期時條件還是沒有出現,pthread_coond_timewait將重新獲取互斥量,然後返回錯誤etimeout。

#include int pthread_cond_wait(pthread_cond_t *restrict cond,

pthread_mutex_t *restrict mutex);

int pthread_cond_timedwait(pthread_cond_t *restrict cond,

pthread_mutex_t *restrict mutex,

const struct timespace *restrict tsptr);

兩個函式的返回值:若成功,返回0;否則,返回錯誤編號

有兩個函式可以用於通知執行緒條件已經滿足。pthread_cond_signal函式至少能喚醒乙個等待該條件的執行緒,而pthread_cond_broadcast函式則能喚醒等待該條件的所有執行緒。

#include int pthread_cond_signal(pthread_cont_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

兩個函式的返回值:若成功,返回0;否則,返回錯誤編號

下面,舉乙個在「執行緒池」中經常用到的任務佇列,當我們將乙個任務放入到任務佇列的時候,可以通過條件變數告知等待執行緒,已經有新任務,可以來取任務執行或當某一線程需要取從任務佇列取任務時候,如果任務隊列為空,則執行緒掛起等待條件變數變為真。

檔案mutext.h

#ifndef __mutex_h__

#define __mutex_h__

#include namespace taskqueue

~cmutexlock()

void lock()

void unlock()

pthread_mutex_t *get()

private:

friend class ccondition;

pthread_mutex_t m_mutex;

}; class cmutexlockpart

~cmutexlockpart()

private:

cmutexlock &m_mutexlock;

};}#endif //#ifndef __mutex_h__

檔案condition.h

#ifndef __condition_h__  

#define __condition_h__

#include "mutex.h"

#include class ccondition

~ccondition()

void wait()

bool waitforseconds(int iseconds)

void signal()

void broadcast()

private:

cmutexlock &m_mutexlock;

pthread_cond_t m_condition;

}; #endif //#ifndef __condition_h__

檔案taskqueue.h

#ifndef __task_queue_h__

#define __task_queue_h__

#include #include "mutex.h"

#include "condition.h"

namespace taskqueue

~ctaskqueue()

void puttask(const t &task)

t gettask()

t rettask = m_queue.front();

m_queue.pop();

return rettask;

} private:

cmutexlock m_mutexlock;

ccondition m_notempty;

queuem_queue;

};}#endif //#ifndef __task_queue_h__

下面為具體的測試**,該測試**建立了2個執行緒,第乙個執行緒負責每2秒向任務佇列裡面放任務,總共放5個任務;第二個執行緒負責從任務佇列裡取任務,並執行任務,共取5次。

#include #include #include #include "taskqueue.h"

using namespace std;

using namespace taskqueue;

static int g_igettaskcount;

typedef void(*taskfunc)(void);

void task(void)

void *funcputtask(void *parg)

pthread_exit((void *)1);

}void *funcgettask(void *parg)

pthread_exit((void *)2); }

* 我們的例子展示的是條件變數的一種使用方式:當我們將乙個任務放入到任務隊

* 列的時候通過條件變數告知掛起執行緒;在取任務佇列時候,如果任務隊列為空

* 那麼就等待任務的到來。

*/int main(void)

iret = pthread_create(&threadgettaskid, null, funcgettask, &taskqueue);

if (iret != 0)

pthread_join(threadputtaskid, null);

pthread_join(threadgettaskid, null);

return 0;

}

我們執行之後的效果為每2秒列印如下所示:

task count: 1

task count: 2

task count: 3

task count: 4

task count: 5

Linux執行緒同步之條件變數

與互斥鎖不同,條件變數是用來等待而不是用來上鎖的。條件變數用來自動阻塞乙個執行緒,直到某特殊情況發生為止。通常條件變數和互斥鎖同時使用。條件變數使我們可以睡眠等待某種條件出現。條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作 乙個執行緒等待 條件變數的條件成立 而掛起 另乙...

Linux執行緒同步之條件變數

條件變數變數也是出自posix 執行緒標準,另一種執行緒同步機制,主要用來等待某個條件的發生。可以用來同步同一程序中的各個執行緒。當然如果乙個條件變數存放在多個程序共享的某個記憶體區中,那麼還可以通過條件變數來進行程序間的同步。每個條件變數總是和乙個互斥量相關聯,條件本身是由互斥量保護的,執行緒在改...

linux執行緒同步之條件變數

條件變數通過允許執行緒阻塞和等待另乙個執行緒傳送訊號的方法彌補了互斥鎖的不足,它常和互斥鎖一起使用。使用時,條件變數被用來阻塞乙個執行緒,當條件不滿足時,執行緒往往解開相應的互斥鎖並等待條件發生變化。一旦其它的某個執行緒改變了條件變數,它將通知相應的條件變數喚醒乙個或多個正被此條件變數阻塞的執行緒。...