1. 程式人生 > 實用技巧 >向你的C語言專案中加入多執行緒

向你的C語言專案中加入多執行緒

C語言在標準庫<pthread.h>中為程式設計師提供了多執行緒操作介面。

先從簡單操作入手

int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine) (void *arg), void *arg) 執行緒建立
int pthread_join( pthread_t thread, void * * value_ptr ) 執行緒等待
int pthread_detach(pthread_t thread) 執行緒分離
int pthread_exit(pthread_t th, void **thr_return)

執行緒結束

pthread_t

pthread_t是表示執行緒號的資料型別。它的出處是/usr/include/bits/pthreadtypes.h

typedef unsigned long int pthread_t

pthread_create

執行緒建立函式,為新執行緒分配資源並且建立成功後執行緒即開始執行,新執行緒的執行緒號即傳參進去的執行緒號。

通過第二個引數指定新執行緒的屬性為“joinable”或“detached”,預設為joinable。若執行緒屬性為joinable,則需要由其他執行緒呼叫pthread_join阻塞等待其結束併為之回收資源,不然就成了"殭屍執行緒";若執行緒屬性為detached,則執行緒結束後自動回收所有資源。

  • 引數說明
int pthread_create(pthread_t *thread,   目標執行緒的執行緒號
                    pthread_attr_t *attr,  設定執行緒的屬性
                    void *(*start_routine) (void *arg), 目標函式的起始地址
                    void *arg) 目標函式的引數 
  • 返回值
    如果執行緒建立成功,返回0; 如果執行緒建立失敗,返回錯誤編號。

pthread_join

當呼叫pthread_join時,當前執行緒進入阻塞狀態,等待被連線的執行緒執行結束返回,當前執行緒再轉回執行狀態。被連線的執行緒必須是非分離的。一個執行緒不能被多個執行緒等待。

  • 引數說明
int pthread_join( pthread_t  thread,      目標執行緒的執行緒號 
                  void * * value_ptr )      目標執行緒的返回值
  • 返回值
    成功則返回0; 失敗則返回錯誤編號。

pthread_detach

將joinable的執行緒設定為detached的執行緒。這樣該執行緒在執行結束後會自動回收其所有資源。

pthread_exit

呼叫pthread_exit可以顯式地結束當前執行緒,傳入的唯一的引數是執行緒的返回值。

掌握基本操作後開始學習新技能

互斥鎖

//兩種方法對鎖進行初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
              const pthread_mutexattr_t *restrict attr);
//互斥鎖的銷燬
int pthread_mutex_destroy(pthread_mutex_t *mutex);

//獲得鎖
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_cond_init(pthread_cond_t *cond,
						pthread_condattr_t *cond_attr);

// 阻塞等待
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);

// 超時等待
int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,
						const timespec *abstime);

// 解除所有執行緒的阻塞
int pthread_cond_destroy(pthread_cond_t *cond);

// 至少喚醒一個等待該條件的執行緒
int pthread_cond_signal(pthread_cond_t *cond);

// 喚醒等待該條件的所有執行緒
int pthread_cond_broadcast(pthread_cond_t *cond);