多線程編程
C語言使用pthread_create()函數(shù)完成多線程的創(chuàng)建,pthread_create()函數(shù)共有四個參數(shù)。這四個參數(shù)分別為:
1. pthread_t *
第一個 參數(shù)負(fù)責(zé)向調(diào)用者傳遞子線程的線程號
2. const pthread_attr_t *
第二這個參數(shù)負(fù)責(zé)控制線程的各種屬性,這也是線程在創(chuàng)建的時候,最為復(fù)雜的一個參數(shù)。下面是這個結(jié)構(gòu)體的定義:
線程屬性結(jié)構(gòu)如下:
typedef struct
{
int detachstate; //線程的分離狀態(tài)
int schedpolicy; //線程調(diào)度策略
structsched_param schedparam; //線程的調(diào)度參數(shù)
int inheritsched; //線程的繼承性
int scope; //線程的作用域
size_t guardsize; //線程棧末尾的警戒緩沖區(qū)大小
int stackaddr_set; //線程堆棧的地址集
void* stackaddr; //線程棧的位置
size_t stacksize; //線程棧的大小
}pthread_attr_t;
2.1 detachstate
在結(jié)構(gòu)體中的第一個參數(shù)detachstate說明了線程的分離狀態(tài)。
PTHREAD_CREATE_DETACHED分離狀態(tài):父線程在創(chuàng)建子線程之后,,父線程不會去等待子線程結(jié)束再去運行自己接下來的程序;
PTHREAD_CREATE_JOINABLE狀態(tài):父線程會等待子線程運行結(jié)束,才繼續(xù)運行接下來的程序。
注意的是如果當(dāng)線程一旦處于PTHREAD_CREATE_DETACHED狀態(tài),那么線程的狀態(tài)就無法再被修改了。線程創(chuàng)建時默認(rèn)設(shè)置為PTHREAD_CREATE_JOINABLE狀態(tài)
這個參數(shù)通過下面的兩個函數(shù)進(jìn)行設(shè)置或者讀取
讀取線程分離狀態(tài):int pthread_attr_getdetachstate(const pthread_attr_t *attr,int detachstate);
設(shè)置線程分離狀態(tài):int pthread_attr_setdetachstate(pthread_attr_t *attr,intdetachstate);
線程的分離狀態(tài)也可以在線程創(chuàng)建之后再去設(shè)置:
pthread_detach()
2.2 schedpolicy
schedpolicy說明的是線程的調(diào)度策略,這個值可以分別被設(shè)置為:
SCHED_FIFO:先進(jìn)先出
SCHED_RR:輪轉(zhuǎn)法
SCHED_OTHER:其他方法
這個參數(shù)可以通過下面的函數(shù)操作:
讀?。?strong>int pthread_attr_getschedpolicy(const pthread_attr_t*attr,int *policy);
設(shè)置:int pthread_attr_setschedpolicy(pthread_attr_t *attr,intpolicy);
2.3 schedparam
schedparam參數(shù)實際上設(shè)置的是線程的優(yōu)先級。這個參數(shù)僅當(dāng)調(diào)度策略為實時(即SCHED_RR或SCHED_FIFO)時才有效
這個參數(shù)可以通過下面的函數(shù)操作:
讀?。?strong>int pthread_attr_getschedparam(const pthread_attr_t*attr,struct sched_param *param);
設(shè)置:int pthread_attr_setschedparam(pthread_attr_t *attr,conststruct sched_param *param);
線程運行時允許對這個值進(jìn)行修改:
pthread_setschedparam()
2.4 inheritsched
這個參數(shù)設(shè)置線程的調(diào)度參數(shù)是拷貝父線程的線程調(diào)度參數(shù),還是上面的兩個參數(shù)schedpolicy和schedparam屬性進(jìn)行設(shè)置。
該參數(shù)可以被設(shè)為:
PTHREAD_INHERIT_SCHED:表示新現(xiàn)成將繼承創(chuàng)建線程的調(diào)度策略和參數(shù))
PTHREAD_EXPLICIT_SCHED:表示使用在schedpolicy和schedparam屬性中顯式設(shè)置的調(diào)度策略和參數(shù)
這個參數(shù)通過下面的兩個函數(shù)進(jìn)行設(shè)置或者讀取
讀?。?strong>int pthread_attr_getinheritsched(const pthread_attr_t*attr,int *inheritsched);
設(shè)置:int pthread_attr_setinheritsched(pthread_attr_t *attr,intinheritsched);
2.5 scope
scope參數(shù)設(shè)置的是線程優(yōu)先級的使用范圍。
PTHREAD_SCOPE_PROCESS 進(jìn)程級競爭資源
PTHREAD_SCOPE_SYSTEM 系統(tǒng)級競爭資源
該參數(shù)可以由下面的函數(shù)操作
讀?。?strong>int pthread_attr_getscope(pthread_attr_t *attr, int *scope);
設(shè)置:int pthread_attr_setscope(pthread_attr_t *attr, int scope);
2.6 stackaddr
這個參數(shù)是線程棧的起始地址,這個參數(shù)只有在線程棧由自己創(chuàng)建時,才需要設(shè)置。當(dāng)線程棧由用戶直接創(chuàng)建,而不是通過系統(tǒng)創(chuàng)建時,線程棧的大小和位置都可以進(jìn)行修改,但是用戶程序需要完成對線程??臻g的釋放。在設(shè)置該參數(shù)之后,guardsize警戒棧緩沖區(qū)的大小就變?yōu)?,為了防止棧溢出就需要對線程棧的境界棧緩沖區(qū)進(jìn)行設(shè)置。
該參數(shù)之前由單獨的函數(shù)進(jìn)行設(shè)置,但是目前已經(jīng)被下面的函數(shù)取代:
讀取:int pthread_attr_getstack(const pthread_attr_t *attr, void *stackaddr, size_t *stacksize);
設(shè)置:int pthread_attr_setstack(pthread_attr_t *attr,void *stackaddr, size_t stacksize);
2.7 guardsize
這個參數(shù)設(shè)置警戒棧緩沖區(qū)的大小。警戒棧緩沖區(qū)可以保護(hù)程序,防止棧溢出對數(shù)據(jù)造成破壞。
這個參數(shù)可以由下面的函數(shù)進(jìn)行操作
讀?。?strong>int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize);
設(shè)置:int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
2.8 stacksize
stacksize參數(shù)在線程創(chuàng)建之前創(chuàng)建,用來修改創(chuàng)建的線程棧的大小,但是最小不能低于PTHREAD_STACK_MIN (16384) bytes,即16k內(nèi)存大小,也就是4個內(nèi)存頁(4個內(nèi)存頁這一點由內(nèi)核決定)。
該參數(shù)可以由下面的函數(shù)操作
讀取:int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);
設(shè)置:int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
3. void *(*start_routine) (void *)
這個參數(shù)負(fù)責(zé)指定子線程需要允許的函數(shù),這個參數(shù)需要的是一個函數(shù)指針。
4. void *
這個參數(shù)負(fù)責(zé)指定,子線程所運行的函數(shù)的參數(shù)值。