概念- 原來指向main()的線程叫做主線程(main thread)
- 使用pthread_create()創(chuàng)建出來的線程,叫做子線程(child thread)
- 主/子線程只有在創(chuàng)建時(shí)才有區(qū)別, 創(chuàng)建完了就一視同仁, 都是一樣的獨(dú)立個(gè)體, 可以有交流、共享和私有, 但沒有上下級(jí), 這一點(diǎn)和多進(jìn)程一樣, 只有在創(chuàng)建的瞬間才有parent process 和child process 的區(qū)別, 創(chuàng)建完了就都是一樣的獨(dú)立個(gè)體
- 創(chuàng)建完子線程之后,兩個(gè)線程之間獨(dú)立運(yùn)行,線程的執(zhí)行先后次序由OS的調(diào)度算法決定
- 線程之間相互獨(dú)立也相互影響,因?yàn)橹骶€程結(jié)束時(shí),會(huì)導(dǎo)致進(jìn)程結(jié)束,進(jìn)程結(jié)束時(shí),會(huì)導(dǎo)致該進(jìn)程的所有線程結(jié)束
- 多個(gè)線程共享一個(gè)進(jìn)程, 而一個(gè)進(jìn)程只有一個(gè)輸出終端, So一定要調(diào)度好, 要不有的線程輸出會(huì)看不到, 最low的做法就是sleep()一下保證線程可以執(zhí)行完
模型
$gcc -pthread#include
pthread_self()
//返回調(diào)用線程的IDpthread_t pthread_self(void);
pthread_equal()
//對(duì)比兩個(gè)線程ID,相等返回非0,不等返回0int pthread_equal(pthread_t t1, pthread_t t2);
pthread_attr_init()/ pthread_attr_destroy()
//pthread_attr_init()初始化一個(gè)線程屬性對(duì)象attr,不指定attr就按默認(rèn)參數(shù)進(jìn)行初始化。//pthread_attr_destroy()銷毀一個(gè)線程屬性對(duì)象,銷毀的操作對(duì)使用這個(gè)attr的線程有影響//成功返回0,失敗返回error numberint pthread_attr_init(pthread_attr_t *attr);int pthread_attr_destroy(pthread_attr_t *attr);
更改attr對(duì)象的函數(shù)
//成功返回0,失敗返回error numbertypedef struct{ int detachstate; //線程的分離狀態(tài) int schedpolicy; //線程調(diào)度策略 struct sched_param schedparam; //線程的調(diào)度參數(shù) int inheritsched; //線程的繼承性 int scope; //線程的作用域 size_t guardsize; //線程棧末尾的警戒緩沖區(qū)大小 int stackaddr_set; //線程的棧設(shè)置 void * stackaddr; //線程棧的位置 size_t stacksize; //線程棧的大小}pthread_attr_t;pthread_attr_setdetachstate(pthread_attr_t* attr, int detachstate)pthread_attr_getdetachstate(const pthread_attr_t* attr, int* detachstate)PTHREAD_CREATE_JOINABLE / PTHREAD_CREAT_DETACHEDint detachstate;pthread_attr_getdetachstate(&attr,&detachstate);if(PTHREAD_CREATE_JOINABLE==detachstate) printf("1.PTHREAD_CREATE_JOINABLE\n"); //defaultpthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);SCHED_OTHER / SCHED_FIFO / SCHED_RRpthread_attr_setsschedchedparam(pthread_attr_t *attr, const struct sched_param *param);pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);struct sched_param { int sched_priority;// Scheduling priority,int sched_get_priority_max/sched_get_priority_min (int policy)};pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched);PTHREAD_INHERIT_SCHED / PTHREAD_EXPLICIT_SCHEDpthread_attr_setscope(pthread_attr_t *attr, int scope);pthread_attr_getscope(const pthread_attr_t *attr, int *scope);PTHREAD_SCOPE_SYSTEM / PTHREAD_SCOPE_PROCESSpthread_attr_setguardsize ( pthread_attr_t *attr, size_t guardsize );pthread_attr_getguardsize ( const pthread_attr_t *attr, size_t *guardsize );>0 / 0(默認(rèn)1 page,當(dāng)然還可以指定任意值)pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize);pthread_attr_setstacksize ( pthread_attr_t *attr, size_t size );pthread_attr_getstacksize ( const pthread_attr_t *attr, size_t *size );
pthread_create()
//這個(gè)函數(shù)的create有‘e’ //p代表POSIX//在調(diào)用進(jìn)程中創(chuàng)建一個(gè)新的線程,新的線程通過激活start_routine()來開始執(zhí)行,arg是start_routine()唯一的參數(shù)//成功返回0,失敗返回error numberint pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
thread:存放新線程的ID到該參數(shù)所指向的緩沖區(qū)中, pthread_t是unsigned long int
attr: 線程的屬性, 給NULL表示默認(rèn)方式
start_routine:指定新線程的處理函數(shù),也就是新線程啟動(dòng)之后需要執(zhí)行的代碼,線程處理函數(shù)執(zhí)行完畢之后, 新線程終止
arg: 用于給start_routine傳遞實(shí)參(VS on_exit()) ,這個(gè)函數(shù)只支持傳遞void*型的型參,實(shí)際使用需要另外定義一個(gè)目標(biāo)類型的指針,將arg強(qiáng)制類型轉(zhuǎn)換后得到正確的類型
pthread_detach()
//將thread表示的線程標(biāo)記為detached,當(dāng)一個(gè)detached的線程結(jié)束后,它占用的資源被自動(dòng)釋放,其他線程也不能用pthread_join()等待//detach一個(gè)已經(jīng)被detach了的線程將導(dǎo)致不確定的結(jié)果//成功返回0,失敗返回error numberint pthread_detach(pthread_t thread);
pthread_setcancelstate()
//設(shè)置當(dāng)前線程是否允許被cancel,成功返回0,失敗返回error number int pthread_setcancelstate(int state, int *oldstate);
state:設(shè)置新狀態(tài)
- PTHREAD_CANCEL_ENABLE //允許取消
- PTHREAD_CANCEL_DISABLE //不允許取消\
oldstate:用于帶出設(shè)置之前的舊狀態(tài)
pthread_setcanceltype()
//設(shè)置可取消性的類型,即當(dāng)前線程何時(shí)被取消 //成功返回0,失敗返回error number int pthread_setcanceltype(int type, int *oldtype);
type:設(shè)置新類型
- PTHREAD_CANCEL_DEFERED //延遲取消
- PTHREAD_CANCEL_ASYNCHRONOUS //立即取消
oldtype:用于帶出設(shè)置之前的舊類型
pthread_exit()
//結(jié)束調(diào)用線程并返回一個(gè)retval值,這個(gè)值可以被同進(jìn)程中的其他線程通過pthread_join()來讀取,當(dāng)然,前提條件是當(dāng)前線程可以被匯合/等待void pthread_exit(void *retval);
線程的3種終止方式:
- 簡(jiǎn)單的從啟動(dòng)例程中返回,返回值是線程的退出碼
- 線程可以被同一進(jìn)程中的其他線程取消
- 線程調(diào)用pthread_exit()
pthread_cancel()
//發(fā)送一個(gè)結(jié)束請(qǐng)求給一個(gè)線程,是否取消以及何時(shí)取消取決于線程的屬性:state和type//成功返回0,失敗返回error numberint pthread_cancel(pthread_t thread);
pthread_join()
//等待thread指定的線程終止,如果目標(biāo)線程沒有終止,則當(dāng)前線程進(jìn)入阻塞狀態(tài),當(dāng)目標(biāo)線程終止時(shí),該函數(shù)立即返回,前提:目標(biāo)線程可以被匯合/等待//如果調(diào)用pthread_join()的線程被cancel了,目標(biāo)線程互保持joinable(不會(huì)被撤銷)//如果多個(gè)線程同時(shí)join一個(gè)線程,那么結(jié)果是不確定的//成功返回0,失敗返回error numberint pthread_join(pthread_t thread, void **retval);
thread:線程編號(hào)
retval:二級(jí)指針的返回值
retval
- 不是NULL,將拷貝目標(biāo)線程的狀態(tài)信息到*retval
- 如果目標(biāo)線程被cancel了,則將PTHREAD_CANCELED防止在*retval
例子
//02join.c, 使用pthread_join等待目標(biāo)線程結(jié)束#include
//03join.c 使用pthread_join獲取目標(biāo)線程的退出狀態(tài)#include
//使用pthread_create()創(chuàng)建新線程#include
//使用pthread_create()創(chuàng)建子線程,在線程處理函數(shù)中計(jì)算1~100之間的和,保存在sum中,返回該變量的地址,主線程等待子線程結(jié)束,并獲取退出狀態(tài)信息,并打印#include
//在線程處理函數(shù)中打印1~20之間的函數(shù),當(dāng)打印到10時(shí)終止當(dāng)前進(jìn)程并帶出10,主線程等待并獲取退出狀態(tài)信息,打印最終結(jié)果#include
//使用pthread_cancel()取消指定的線程#include
評(píng)論
查看更多