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