多線程-條件變量屬性
使用條件變量可以以原子方式阻塞線程,直到某個特定條件為真為止。條件變量始終與互斥鎖一起使用。
使用條件變量,線程可以以原子方式阻塞,直到滿足某個條件為止。對條件的測試是在互斥鎖(互斥)的保護下進行的。
如果條件為假,線程通常會基于條件變量阻塞,并以原子方式釋放等待條件變化的互斥鎖。如果另一個線程更改了條件,該線程可能會向相關的條件變量發出信號,從而使一個或多個等待的線程執行以下操作:
-
喚醒
-
再次獲取互斥鎖
-
重新評估條件
在以下情況下,條件變量可用于在進程之間同步線程:
-
線程是在可以寫入的內存中分配的
-
內存由協作進程共享
調度策略可確定喚醒阻塞線程的方式。對于缺省值 SCHED_OTHER,將按優先級順序喚醒線程。
必須設置和初始化條件變量的屬性,然后才能使用條件變量。表 4–4 列出了用于處理條件變量屬性的函數。
表 4–4 條件變量屬性
操作 |
函數說明 |
---|---|
初始化條件變量屬性 |
|
刪除條件變量屬性 |
|
設置條件變量的范圍 |
|
獲取條件變量的范圍 |
表 4–5 中顯示了定義條件變量的范圍時 Solaris 線程和 POSIX 線程之間的差異。
表 4–5 條件變量范圍比較
Solaris |
POSIX |
定義 |
---|---|---|
USYNC_PROCESS |
PTHREAD_PROCESS_SHARED |
用于同步該進程和其他進程中的線程 |
USYNC_THREAD |
PTHREAD_PROCESS_PRIVATE |
用于僅同步該進程中的線程 |
初始化條件變量屬性
使用 pthread_condattr_init(3C) 可以將與該對象相關聯的屬性初始化為其缺省值。在執行過程中,線程系統會為每個屬性對象分配存儲空間。
pthread_condattr_init 語法
int pthread_condattr_init(pthread_condattr_t *cattr);
#include <pthread.h> pthread_condattr_t cattr; int ret; /* initialize an attribute to default value */ ret = pthread_condattr_init(&cattr);
調用此函數時,pshared 屬性的缺省值為 PTHREAD_PROCESS_PRIVATE。pshared 的該值表示可以在進程內使用已初始化的條件變量。
cattr 的數據類型為 opaque,其中包含一個由系統分配的屬性對象。cattr 范圍可能的值為 PTHREAD_PROCESS_PRIVATE 和 PTHREAD_PROCESS_SHARED。PTHREAD_PROCESS_PRIVATE 是缺省值。
條件變量屬性必須首先由 pthread_condattr_destroy(3C) 重新初始化后才能重用。pthread_condattr_init() 調用會返回指向類型為 opaque 的對象的指針。如果未銷毀該對象,則會導致內存泄漏。
pthread_condattr_init 返回值
pthread_condattr_init() 在成功完成之后會返回零。其他任何返回值都表示出現了錯誤。如果出現以下任一情況,該函數將失敗并返回對應的值。
ENOMEM
描述:分配的內存不足,無法初始化線程屬性對象。
EINVAL
描述:cattr 指定的值無效。
刪除條件變量屬性
使用 pthread_condattr_destroy(3C) 可以刪除存儲并使屬性對象無效。
pthread_condattr_destroy 語法
int pthread_condattr_destroy(pthread_condattr_t *cattr);
#include <pthread.h> pthread_condattr_t cattr; int ret; /* destroy an attribute */ ret = pthread_condattr_destroy(&cattr);
pthread_condattr_destroy 返回值
pthread_condattr_destroy() 在成功完成之后會返回零。其他任何返回值都表示出現了錯誤。如果出現以下情況,該函數將失敗并返回對應的值。
EINVAL
描述:cattr 指定的值無效。
設置條件變量的范圍
pthread_condattr_setpshared(3C) 可用來將條件變量的范圍設置為進程專用(進程內)或系統范圍內(進程間)。
pthread_condattr_setpshared 語法
int pthread_condattr_setpshared(pthread_condattr_t *cattr, int pshared);
#include <pthread.h> pthread_condattr_t cattr; int ret; /* all processes */ ret = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED); /* within a process */ ret = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_PRIVATE);
如果 pshared 屬性在共享內存中設置為 PTHREAD_PROCESS_SHARED,則其所創建的條件變量可以在多個進程中的線程之間共享。此行為與最初的 Solaris 線程實現中 mutex_init() 中的 USYNC_PROCESS 標志等效。
如果互斥鎖的 pshared 屬性設置為 PTHREAD_PROCESS_PRIVATE,則僅有那些由同一個進程創建的線程才能夠處理該互斥鎖。PTHREAD_PROCESS_PRIVATE 是缺省值。PTHREAD_PROCESS_PRIVATE 所產生的行為與在最初的 Solaris 線程的 cond_init() 調用中使用 USYNC_THREAD 標志相同。PTHREAD_PROCESS_PRIVATE 的行為與局部條件變量相同。PTHREAD_PROCESS_SHARED 的行為與全局條件變量等效。
pthread_condattr_setpshared 返回值
pthread_condattr_setpshared() 在成功完成之后會返回零。其他任何返回值都表示出現了錯誤。如果出現以下情況,該函數將失敗并返回對應的值。
EINVAL
描述:cattr 或 pshared 的值無效。
獲取條件變量的范圍
pthread_condattr_getpshared(3C) 可用來獲取屬性對象 cattr 的 pshared 的當前值。
pthread_condattr_getpshared 語法
int pthread_condattr_getpshared(const pthread_condattr_t *cattr, int *pshared);
#include <pthread.h> pthread_condattr_t cattr; int pshared; int ret; /* get pshared value of condition variable */ ret = pthread_condattr_getpshared(&cattr, &pshared);
屬性對象的值為 PTHREAD_PROCESS_SHARED 或 PTHREAD_PROCESS_PRIVATE。
pthread_condattr_getpshared 返回值
pthread_condattr_getpshared() 在成功完成之后會返回零。其他任何返回值都表示出現了錯誤。如果出現以下情況,該函數將失敗并返回對應的值。
EINVAL
描述:cattr 的值無效。