Linux多線程編程(一)

  • 2019 年 10 月 6 日
  • 筆記

一番碼客 : 挖掘你關心的亮點。 http://efonfighting.imwork.net

1 – 線程創建

pthread_create

創建一個線程,函數的聲明:

int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,                     void* (*start_routine)(void*), void* arg)  
  • para:
    • thread_out:創建線程後的標識符。
    • attr:設置線程屬性。傳NULL為默認屬性。
    • start_routine:線程運行函數的函數指針。
    • arg:運行函數的參數,不使用參數則為NULL。
  • return:
    • 0:創建成功。
    • 非0:創建失敗,常見錯誤返回代碼EAGAIN(統限制創建新的線程,例如線程數目過多)和EINVAL(線程屬性值非法)。

pthread_t

定義在 pthreadtypes.h

typedef unsigned long int pthread_t;  

線程的標識符。也就是前面創建線程時候傳入的參數。

2 – 線程屬性設置

pthread_attr_t

屬性對象主要包括是否綁定、是否分離、堆棧地址、堆棧大小、優先級。默認的屬性為非綁定、非分離、缺省1M的堆棧、與父進程同樣級別的優先級。pthread_attr_t結構的定義,定義在pthread.h

typedef struct  {      uint32_t flags;      void * stack_base;      size_t stack_size;      size_t guard_size;      int32_t sched_policy;      int32_t sched_priority;  } pthread_attr_t;  

屬性設置

  • 初始化:pthread_attr_init
  • 默認屬性:非綁定、非分離、1M堆棧、與父進程同樣級別的優先級。
  • 設置:屬性值只能通過相關函數(**pthread_attr_set×××**)進行設置,這個函數必須在pthread_create函數之前調用。
  • 屬性操作函數:
/*      功能:初始化一個線程對象的屬性      返回值:若是成功返回0,否則返回錯誤的編號      形參:attr指向一個線程屬性的指針      說明:Posix線程中的線程屬性pthread_attr_t主要包括scope屬性、detach屬性、堆棧地址、堆棧大小、優先級。pthread_attr_init實現時為屬性對象分配了動態內存空間。  */  int pthread_attr_init(pthread_attr_t *attr);      /*      功能:銷毀一個線程屬性對象      返回值:若是成功返回0,否則返回錯誤的編號      形參:attr指向一個線程屬性的指針      說明:經pthread_attr_destroy去除初始化之後的pthread_attr_t結構被pthread_create函數調用,將會導致其返回錯誤。  */  int pthread_attr_destroy(pthread_attr_t *attr);    3、獲取線程間的CPU親緣性  int pthread_attr_getaffinity_np(pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針      說  明:獲取線程的CPU親緣屬性      頭文件:#include <pthread.h>  4、設置線程的CPU親緣性  int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr         指向一個線程屬性的指針              cpusetsize   指向CPU組的緩衝區大小              cpuset       指向CPU組的指針      說  明:通過指定cupset來設置線程的CPU親緣性      頭文件:#include <pthread.h>  5、獲取線程分離狀態屬性  int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr          指向一個線程屬性的指針              detachstate   保存返回的分離狀態屬性      說  明:獲取線程分離狀態屬性      頭文件:#include <pthread.h>  6、修改線程分離狀態屬性  int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr        指向一個線程屬性的指針              detachstat  有兩個取值                          PTHREAD_CREATE_DETACHED(分離)                          PTHREAD_CREATE_JOINABLE(非分離)      說  明:Posix線程中的線程屬性pthread_attr_t主要包括scope屬性、detach屬性、堆棧地址、堆棧大小、優先級。      頭文件:#include <pthread.h>  7、獲取線程的棧保護區大小  int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              guardsize  返回獲取的棧保護區大小      說  明:獲取線程的棧保護區大小      頭文件:#include <pthread.h>  8、設置線程的棧保護區大小  int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              guardsize  線程的棧保護區大小      說  明:參數提供了對棧指針溢出的保護。              默認為系統頁大小              如果設置為0表示沒有保護區。              大於0,則會為每個使用 attr 創建的線程提供大小至少為 guardsize 位元組的溢出保護區      頭文件:#include <pthread.h>  9、獲取線程的作用域  int pthread_attr_getscope(pthread_attr_t *attr, int *scope);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              scope      返回線程的作用域      說  明:指定了作用域也就指定了線程與誰競爭資源      頭文件:#include <pthread.h>  10、設置線程的作用域  int pthread_attr_setscope(pthread_attr_t *attr, int scope);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              guardsize  線程的作用域,可以取如下值                         PTHREAD_SCOPE_SYSTEM    與系統中所有進程中線程競爭                         PTHREAD_SCOPE_PROCESS   與當前進程中的其他線程競爭      說  明:指定了作用域也就指定了線程與誰競爭資源      頭文件:#include <pthread.h>  11、獲取線程的堆棧信息(棧地址和棧大小)  int pthread_attr_getstack(pthread_attr_t *attr, void **stackaddr, size_t *stacksize);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              stackaddr  返回獲取的棧地址              stacksize  返回獲取的棧大小      說  明:獲取線程的堆棧地址和大小      頭文件:#include <pthread.h>  12、設置線程堆棧區  int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              stackaddr  線程的堆棧地址:應該是可移植的,對齊頁邊距的                         可以用posix_memalign來進行獲取              stacksize  線程的堆棧大小:應該是頁大小的整數倍      說  明:設置堆棧區,將導致pthread_attr_setguardsize失效。      頭文件:#include <pthread.h>  13、獲取線程堆棧地址  int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              stackaddr  返回獲取的棧地址      說  明:函數已過時,一般用pthread_attr_getstack來代替      頭文件:#include <pthread.h>  14、設置線程堆棧地址  int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              stackaddr  設置線程堆棧地址      說  明:函數已過時,一般用pthread_attr_setstack來代替      頭文件:#include <pthread.h>  15、獲取線程堆棧大小  int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              stacksize  返回線程的堆棧大小      說  明:獲取線程堆棧大小      頭文件:#include <pthread.h>  16、設置線程堆棧大小  int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              guardsize  線程的棧保護區大小:應該是頁大小的整數倍      說  明:設置線程堆棧大小:      頭文件:#include <pthread.h>  17、獲取線程的調度策略  int pthread_attr_getschedpolicy(pthread_attr_t *attr, int *policy);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              policy     返回線程的調度策略      說  明:獲取線程的調度策略      頭文件:#include <pthread.h>  18、設置線程的調度策略  int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              policy     線程的調度策略,有如下三種:                          SCHED_FIFO    先入先出策略                          SCHED_RR      輪轉調度,類似於 FIFO,但加上了時間輪片算法                          SCHED_OTHER      系統默認策略      說  明:設置線程的調度策略      頭文件:#include <pthread.h>  19、獲取線程的調度參數  int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              param      返回獲取的調度參數,該結構僅有一個從參數,如下                          struct sched_param                          {                              int sched_priority; /* Scheduling priority */                          };      說  明:獲取線程的調度參數      頭文件:#include <pthread.h>  20、設置線程的調度參數  int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param *param);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              param      要設置的調度參數      說  明:設置線程的調度參數      頭文件:#include <pthread.h>  21、獲取線程是否繼承調度屬性  int pthread_attr_getinheritsched(pthread_attr_t *attr, int *inheritsched);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr          指向一個線程屬性的指針              inheritsched  返回繼承調度屬性的設置      說  明:獲取線程是否繼承調度屬性      頭文件:#include <pthread.h>  22、設置線程是否繼承調度屬性  int pthread_attr_getinheritsched(pthread_attr_t *attr, int *inheritsched);      返回值:若是成功返回0,否則返回錯誤的編號      形  參:              attr       指向一個線程屬性的指針              guardsize  設置線程是否繼承調度屬性                          PTHREAD_INHERIT_SCHED:調度屬性將繼承於正創建的線程                                                 attr中的設置將被忽略                          PTHREAD_EXPLICIT_SCHED 調度屬性將被設置為attr中指定的屬性值      說  明:      頭文件:#include <pthread.h>  

線程參數傳遞

參數傳遞的是指針。代碼中將value的值傳入。

pthread_create(&id, &attr, run, &value);  

然後進行指針變量類型轉換就可得到值。

int value=*(int *)ptr;  

3 – 線程優先級

主要涉及sched_parampthread_attr_setschedparampthread_attr_getschedparam等方法。

優先級變量存放在結構sched_param中。用pthread_attr_getschedparampthread_attr_setschedparam進行存放,一般說來,我們總是先取優先級,對取得的值修改後再存放回去。

免費知識星球: 一番碼客-積累交流 微信公眾號:一番碼客 微信:Efon-fighting 網站:http://efonfighting.imwork.net