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_param
、pthread_attr_setschedparam
、pthread_attr_getschedparam
等方法。
優先級變量存放在結構sched_param
中。用pthread_attr_getschedparam
和pthread_attr_setschedparam
進行存放,一般說來,我們總是先取優先級,對取得的值修改後再存放回去。
免費知識星球: 一番碼客-積累交流 微信公眾號:一番碼客 微信:Efon-fighting 網站:http://efonfighting.imwork.net