您好,登錄后才能下訂單哦!
線程的控制
線程的創(chuàng)建:
線程創(chuàng)建函數(shù):int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine(void*),void *arg);
返回值:成功返回0,失敗返回錯(cuò)誤號。
在一個(gè)線程中調(diào)用pthread_create()創(chuàng)建新的線程后,當(dāng)前線程從pthread_create()返回繼續(xù)往下執(zhí)行,而新的線程所執(zhí)行的代碼由我們傳給pthread_create()的函數(shù)指針star_routine決定。pthread_create成功返回后,新創(chuàng)建的線程id被填寫到thread參數(shù)所指向的內(nèi)存單元。線程id的類型是thread_t,它只在當(dāng)前進(jìn)程中保證是唯一的,在不同的系統(tǒng)中thread_t這個(gè)類型有不同的實(shí)現(xiàn),它可能是一個(gè)整數(shù)值,也可能是一個(gè)結(jié)構(gòu)體,也可能是一個(gè)地址,用pthread_self()可獲得當(dāng)前線程id。
如果任意一個(gè)線程調(diào)用了exit或_exit,則整個(gè)進(jìn)程的所有線程都終止。
線程的終止:
有以下三種方法終止線程:
從線程函數(shù)return,這種方法對主線程不適用,從main函數(shù)return相當(dāng)于調(diào)用exit;
一個(gè)線程可以調(diào)用pthread_cancel終止統(tǒng)一進(jìn)程中的另一個(gè)線程;
程可以調(diào)用pthread_exit終自己;
下面我們看一段代碼,看看這3中方法的區(qū)別:
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
void *thread1(void *arg)
{
printf("thread 1 returning....\n");
return (void*)1;
}
void *thread2(void *arg)
{
printf("thread 1 exiting....\n");
pthread_exit((void*)2);
}
void *thread3(void *arg)
{
while(1)
{
printf("thread 3 is runing,wait to bu cancel...\n");
sleep(1);
}
return NULL;
}
int main()
{
pthread_t tid;
void *val;
pthread_create(&tid,NULL,thread1,NULL);
pthread_join(tid,&val);
printf("thread return,thread id is:%u,return code is:%d\n",tid,(int)val);
pthread_create(&tid,NULL,thread2,NULL);
pthread_join(tid,&val);
printf("thread exit,thread id is:%u,exit code is:%d\n",tid,(int)val);
pthread_create(&tid,NULL,thread3,NULL);
sleep(3);
pthread_cancel(tid);
pthread_join(tid,&val);
printf("thread return,thread id is:%u,return code is:%d\n",tid,(int)val);
return 0;
}
運(yùn)行結(jié)果如下:
一般情況下,線程終止后,其狀態(tài)一直保留到其他線程調(diào)用pthread_join獲取它的狀態(tài)為止,但是線程也可以被置為detach狀態(tài),這樣的線程一旦終止,就立刻回收它所占有的所有資源,而不保留終止?fàn)顟B(tài),不能對一個(gè)處于detach狀態(tài)的線程調(diào)用pthread_join,這樣的調(diào)用將返回EINVAL,對一個(gè)尚未detach的線程調(diào)用pthread_join或pthread_detach都可以把該線程置為detach狀態(tài)。也就是說不能對一個(gè)線程調(diào)用兩次pthread_join 或者已經(jīng)對一個(gè)線程調(diào)用了pthread_detach,就不能再調(diào)用pthread_join了。
線程分離
在任何一個(gè)時(shí)間點(diǎn)上,線程是可結(jié)合的或者是可分離的,一個(gè)可結(jié)合的線程能夠被其他線程收回其資源和殺死,在被其他線程收回之前,它的存儲資源是不釋放的。相反,一個(gè)分離的線程是不能被其他線程回收或殺死的,他的存儲器資源在它終止時(shí)由系統(tǒng)自動釋放。
默認(rèn)情況下,線程被創(chuàng)建成可結(jié)合的,為了避免存儲器泄露,每個(gè)可結(jié)合線程要么被顯示的回收,要么調(diào)用pthread_detach函數(shù)被分離。
由于調(diào)用pthread_join后,如果該線程沒有運(yùn)行結(jié)束,調(diào)用者會被阻塞,我們并不希望如此。我們這時(shí)可以在子線程代碼中加入pthread_detach(pthread_self())或者父線程調(diào)用pthread_detach(tid).這將子線程的狀態(tài)設(shè)置為分離的,該線程運(yùn)行結(jié)束后會自動釋放所有資源。
下面我們看一段代碼:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
void *thread(void *arg)
{
pthread_detach(pthread_self());
printf("thread 1 returning....\n");
return NULL;
}
int main()
{
pthread_t tid;
int ret=pthread_create(&tid,NULL,thread,NULL);
if(ret!=0)
{
printf("create thread error,info is :%s\n",strerror(ret));
}
sleep(1);
if(0==pthread_join(tid,NULL))
{
printf("thread wait success\n");
}
else
{
printf("thread wait failed\n");
}
return 0;
}
運(yùn)行結(jié)果:
從結(jié)果可以看到,我們在子線程里面用了pthread_detach,在主線程里面又用了pthread_join,所以會wait failed。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。