執行緒按照其排程者可以分為使用者級執行緒和核心級執行緒兩種。
(1)使用者級執行緒
如果乙個程序中的某乙個執行緒呼叫了乙個阻塞的系統呼叫,那麼該程序包括該程序中的其他 所有執行緒也同時被阻塞。這種使用者級執行緒的主要缺點是在乙個程序中的多個執行緒的排程中無 法發揮多處理器的優勢。
(2)核心級執行緒
這種執行緒允許不同程序中的執行緒按照同一相對優先排程方法進行排程,這樣就可以發揮 多處理器的併發優勢。
int pthread_create ((pthread_t *thread, pthread_attr_t *attr, void *(* start_routine)(void *), void *arg))
start_routine是執行緒函式的起始位址
void pthread_exit(void *retval)
retval是呼叫者執行緒的返回值,即使用不呼叫pthread_exit(),執行緒函式執行完之後執行緒也會自動退出,就像int main()即使最後沒有return語句程式也會自動退出一樣。
int pthread_join ((pthread_t th, void **thread_return))
thread_return:使用者定義的指標,用來儲存被等待執行緒的返回值(不為 null 時)
pthread_create 函式的第二個引數--
執行緒的屬性
,將該值設為 null,也就是採用預設屬性,執行緒的多項屬性都是可以更改的。這些屬性主要包括繫結屬性、分離屬性、堆疊位址、堆疊大小、優先順序。其中系統預設的屬性為非繫結、非分離、預設1m 的堆疊、與父程序同樣級別的優先順序。
• 繫結屬性
linux 中乙個使用者執行緒對應乙個核心執行緒。繫結屬性就是指乙個使用者執行緒固定地分配給乙個核心執行緒, 非繫結屬性就是指使用者執行緒和核心執行緒的關係不是始終固定的,而是由系統來控制分配的。
cpu 時間片的排程是面向核心執行緒(也就是輕量級程序)的。
• 分離屬性
分離屬性是用來決定乙個執行緒以什麼樣的方式來終止自己。在非分離情況下,
當乙個線
程結束時,
它所占用的系統資源並沒有被釋放,
也就是沒有真正的終止。
只有當 pthread_join()
函式返回時,
建立的執行緒才能釋放自己占用的系統資源。而在分離屬性情況下,
乙個執行緒結
束時立即釋放它所占有的系統資源。這裡要注意的一點是,
如果設定乙個執行緒的分離屬性,
而這個執行緒執行又非常快,
那麼它很可能在pthread_create
函式返回之前就終止了,
它終止以
後就可能將執行緒號和系統資源移交給其他的執行緒使用,
這時呼叫 pthread_create
的執行緒就得到
了錯誤的執行緒號。
struct sched_param
;
#include#include#include
#include
void run1(void
) sleep(1);
}}void run2(void
) pthread_exit(0);
}int
main()
//建立執行緒
ret=pthread_create(&p2,&attr2,(void*)run2,null);
if(ret==-1
)
//等待執行緒結束
1.mutex互斥鎖線程控制
若乙個執行緒希望上鎖乙個已經上鎖的互斥鎖,則該執行緒就會掛起,直到上鎖的執行緒釋放掉互斥鎖。
互斥鎖的操作主要包括以下幾個步驟。
• 互斥鎖初始化:pthread_mutex_init
• 互斥鎖上鎖:int pthread_mutex_lock(pthread_mutex_t *mutex)
• 互斥鎖判斷上鎖:int pthread_mutex_trylock(pthread_mutex_t *mutex )
• 互斥鎖接鎖:int pthread_mutex_unlock(pthread_mutex_t *mutex)
• 消除互斥鎖:int pthread_mutex_destroy(pthread_mutex_t *mutex)
其中,互斥鎖可以分為快速互斥鎖、遞迴互斥鎖和檢錯互斥鎖。這三種鎖的區別主要在於其他未占有互斥鎖的執行緒在希望得到互斥鎖時的是否需要阻塞等待。快速鎖是指呼叫執行緒會阻塞直至擁有互斥鎖的執行緒解鎖為止。遞迴互斥鎖能夠成功地返回並且增加呼叫執行緒在互斥上加鎖的次數,而檢錯互斥鎖則為快速互斥鎖的非阻塞版本,它會立即返回並返回乙個錯誤資訊。
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
引數mutexattr 的取值:
pthread_mutex_initializer:建立快速互斥鎖
pthread_recursive_mutex_initializer_np:建立遞迴互斥鎖
pthread_errorcheck_mutex_initializer_np: 建立檢錯互斥鎖
2.訊號量執行緒控制
#include
int sem_init(sem_t *sem,int pshared,unsigned int value) /*建立並初始化訊號量*/
sem:訊號量
pshared:決定訊號量能否在幾個程序間共享。由於目前 linux 還沒有實現程序間共享訊號量,所以這個值只能夠取 0
value:訊號量初始化值
#include
int sem_wait(sem_t *sem) /*相當於p操作,若訊號量小於0,則會阻塞程序*/
int sem_trywait(sem_t *sem) /*相當於p操作,若訊號量小於0,則函式會立即返回*/
int sem_post(sem_t *sem) /*相當於v操作*/
int sem_getvalue(sem_t *sem) /*得到訊號量的值*/
int sem_destroy(sem_t *sem) /*刪除訊號量*/
同樣可以用訊號量同步的機制實現上面的功能:
多執行緒程式設計
1 多執行緒的基本思路不是在介面執行緒執行費時的 而是專門啟動乙個執行緒 稱作工作執行緒 來完成,介面執行緒只負責介面的 顯示 和操作,而工作執行緒只負責耗時的操作過程。2 對於普通的win32應用程式來說,執行緒可以分為兩種 介面 ui user inte ce 執行緒和工作執行緒。介面執行緒一般...
多執行緒程式設計
如何編寫執行緒安全的dll 在我的工作中經常會編寫dll,這些dll有個共同的特點就是都有乙個初始化函式,乙個資源釋放函式,其他幾個函式都是核心功能函式。而且這些dll有時會被多個程序同時呼叫,這就牽扯到多程序的多執行緒呼叫dll的問題。有點繞口,以下我根據我實踐中遇到的問題,分四種情況分享一下我解...
多執行緒程式設計
1 執行緒的狀態 建立狀態 準備好了乙個多執行緒的物件 就緒狀態 呼叫了start 方法,等待cpu進行排程 執行狀態 執行run 方法 阻塞狀態 暫時停止執行,可能將資源交給其他執行緒使用 終止狀態 死亡狀態 執行緒銷毀 2 執行緒的常用方法 thread類 取得執行緒名稱 getname thr...