POSIX執行緒程式設計起步(2)-執行緒同步 (轉)
2.執行緒同步
POSIX提供了兩種用於執行緒同步的原語,這兩種操作分別是互斥以及條件變數。互斥是一種簡單的進行鎖定的原語,其主要作用是控制對共享資源的訪問,防止衝突。關於多執行緒,有一點值得大家注意,那就是整個的地址空間有所有的執行緒共享。其結果是幾乎所有的資源都可以被共享——比如全域性變數、描述符等。另一方面,在每個執行緒的入口(由pthread_create)內,以及由該函式呼叫的其他函式內,我們都會定義一些私有的區域性變數。在多執行緒程式中,全域性變數與區域性變數總是被混合使用,要想使多執行緒程式順利的執行,各執行緒對共享資源的訪問必須得到控制。
以下是一個生產者/消費者程式。生產者與消費者對共享緩衝區的訪問由互斥進行控制。
void * reader_function(void *);
void * writer_function(void *);
char buffer;
int buffer_has_item = 0;
pthread_mutex_t mutex;
struct timespec delay;
main()
{
pthread_t reader;
delay.tv_sec = 2;
delay.tv_nsec = 0;
pthread_mutex_init(&mutex, pthread_mutexattr_default);
pthread_create( &reader, pthread_attr_default, reader_function,
NULL);
writer_function();
}
void * writer_function(void *)
{
while(1)
{
pthread_mutex_lock( &mutex );
if ( buffer_has_item == 0 )
{
buffer = make_new_item();
buffer_has_item = 1;
}
pthread_mutex_unlock( &mutex );
pthread_delay_np( &delay );
}
}
void * reader_function(void *)
{
while(1)
{
pthread_mutex_lock( &mutex );
if ( buffer_has_item == 1)
{
consume_item( buffer );
buffer_has_item = 0;
}
pthread_mutex_unlock( &mutex );
pthread_delay_np( &delay );
}
}
上邊這個簡單的例子程式中,共享緩衝區只能儲存一個共享資料項。因此該緩衝區只有兩個狀態:“有”/“無”。生產者在向緩衝區寫入資料前,首先會將互斥上鎖,如果該互斥已被鎖定,則生產者將阻塞直到互斥被解鎖。生產者鎖定了互斥以後,將會檢查緩衝區是否為空(透過標誌變數buffer_has_item)。如果緩衝區沒有資料,生產者就會產生新資料項放入緩衝區,並設定標誌變數以使得消費者可以知道是否能進行消費。接下來生產者解除對互斥的鎖定並等待,這樣消費者應該有充足的時間來訪問緩衝區。
消費者採取了相似的過程來訪問緩衝區。它首先鎖定互斥,檢查標誌變數,如果可能則消費掉僅有的資料項。接著消費者解鎖互斥並等待一小會兒好讓生產者有時間寫入新的資料項。
上例中,生產者和消費者將會持續不斷的執行,不斷的生產、消費。事實上,在通常的程式中,如果確定不再使用某個互斥,則應該用pthread_mutex_destroy(&mutex)將其摧毀。順便提一句,在使用某個互斥之前,應該使用pthread_mutex_init()將其初始化。在我們的例子中,初始化時使用了兩個引數,第一個用來指定被初始化的互斥,第二個則是該互斥的屬性。(在DEC O/1上,互斥的屬性沒有實際意義,通常使用PTHREAD_MUTEXATTR_DEFAULT)
對互斥的正確使用可以有效地減少競爭條件。其實互斥本身是非常簡單的,只有兩個狀態:鎖定、未鎖定。它能實現的功能也是有限的。POSIX還提供了條件變數這一有力工具來補充互斥的不足。使用條件變數,一個執行緒可以在已經鎖定互斥的情況下被阻塞並等待喚醒訊號,而其他執行緒仍能訪問被鎖定的共享資源。當另外的某一個執行緒發出訊號後,被阻塞的執行緒將被喚醒並依然可以訪問阻塞前自己鎖定的共享資源。由此,互斥和條件變數的聯合使用可以幫助我們避免迴圈死鎖的情況出現。我們利用互斥和條件變數設計了一個僅有單一整數訊號燈的庫。庫的可以在附錄A中找到,關於條件變數的說明可以在手冊頁(man pages)裡找到
本節涉及的函式:
pthread_mutex_init(), pthread_mutex_lock(),
pthread_mutex_unlock(), and pthread_mutex_destroy().
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-960949/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Posix執行緒程式設計指南(3)-執行緒同步 (轉)執行緒程式設計
- POSIX執行緒程式設計起步(1)-Hello World (轉)執行緒程式設計
- Posix執行緒程式設計指南(2)-執行緒私有資料 (轉)執行緒程式設計
- Posix執行緒程式設計指南(4)-執行緒終止 (轉)執行緒程式設計
- Posix執行緒程式設計指南(1)-執行緒建立與取消 (轉)執行緒程式設計
- .NET多執行緒程式設計(3):執行緒同步 (轉)執行緒程式設計
- Posix執行緒程式設計指南(5)-Misc (轉)執行緒程式設計
- POSIX執行緒詳解(2) (轉)執行緒
- .NET多執行緒程式設計(4):執行緒池和非同步程式設計 (轉)執行緒程式設計非同步
- iOS多執行緒程式設計:執行緒同步總結iOS執行緒程式設計
- POSIX執行緒詳解 (轉)執行緒
- POSIX 執行緒詳解(3) (轉)執行緒
- java執行緒程式設計(一):執行緒基礎(轉)Java執行緒程式設計
- C#多執行緒程式設計-基元執行緒同步構造C#執行緒程式設計
- 4、Linux多執行緒,執行緒同步(2)Linux執行緒
- 多執行緒(2)-執行緒同步互斥鎖Mutex執行緒Mutex
- python多執行緒程式設計3: 使用互斥鎖同步執行緒Python執行緒程式設計
- 多執行緒程式設計(轉)執行緒程式設計
- c#執行緒-執行緒同步C#執行緒
- 執行緒同步及執行緒鎖執行緒
- 程式設計思想之多執行緒與多程式(2):執行緒優先順序與執行緒安全程式設計執行緒
- [短文速讀 -5] 多執行緒程式設計引子:程式、執行緒、執行緒安全執行緒程式設計
- Q:你瞭解非同步程式設計、程式、單執行緒、多執行緒嗎?非同步程式設計執行緒
- 多執行緒(2)-執行緒同步條件變數執行緒變數
- java併發程式設計——執行緒同步Java程式設計執行緒
- 執行緒同步(C#程式設計指南)執行緒C#程式設計
- 併發程式設計之多執行緒執行緒安全程式設計執行緒
- 多執行緒和多執行緒同步執行緒
- 【轉】1.1非同步程式設計:執行緒概述及使用非同步程式設計執行緒
- .NET多執行緒程式設計(1):多工和多執行緒 (轉)執行緒程式設計
- 【多執行緒總結(二)-執行緒安全與執行緒同步】執行緒
- 執行緒同步執行緒
- 使用執行緒池優化多執行緒程式設計執行緒優化程式設計
- DELPHI下的多執行緒程式設計(2) (轉)執行緒程式設計
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- JavaScript 單執行緒之非同步程式設計JavaScript執行緒非同步程式設計
- Java執行緒:執行緒的同步與鎖Java執行緒
- Java多執行緒程式設計筆記2:synchronized同步方法Java執行緒程式設計筆記synchronized