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