一.有關(guān)于線程的定義
成都創(chuàng)新互聯(lián)主營(yíng)崇義網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,重慶App定制開發(fā),崇義h5小程序開發(fā)搭建,崇義網(wǎng)站營(yíng)銷推廣歡迎崇義等地區(qū)企業(yè)咨詢
線程是進(jìn)程執(zhí)行的一個(gè)分支,運(yùn)行在進(jìn)程的內(nèi)部,是調(diào)度的一個(gè)基本單元。線程不像進(jìn)程強(qiáng)調(diào)獨(dú)占,它更多強(qiáng)調(diào)的是共享。一個(gè)進(jìn)程可以有多個(gè)控制流程即有多個(gè)線程,進(jìn)程是承擔(dān)和分配系統(tǒng)資源的基本實(shí)體。
舉個(gè)例子:
進(jìn)程好比是一個(gè)大家庭,而線程就相當(dāng)于是家里的每一個(gè)成員,每個(gè)成員各司其職,共同讓這個(gè)大家庭變得更好。這個(gè)大家庭的資源,每個(gè)成員都可以共享,但這并不是絕對(duì)的。因?yàn)槊總€(gè)成員都有自己私有的空間或秘密等。所以線程有和進(jìn)程共同的東西,也有自己私有的。
線程和進(jìn)程共同的:
1.文件描述符表:描述當(dāng)前進(jìn)程所打開的所有文件;
2.當(dāng)前工作目錄;
3.用戶id;
4.信號(hào)處理方式
線程私有的:(2和3 是重點(diǎn))
1.線程的id;
2.硬件上下文,包括各寄存器的值,棧指針和程序計(jì)數(shù)器;
3.??臻g(線程自己的);
4.errno變量;
5.信號(hào)屏蔽字;//處理需要處理的,屏蔽不需處理的
6.調(diào)度優(yōu)先級(jí);
二.線程的控制
1.線程的創(chuàng)建
線程的創(chuàng)建是由POSIX 標(biāo)準(zhǔn)定義的,稱為POSIX thread 或pthread。在編譯的時(shí)候要加上_lpthread選項(xiàng)。
線程的創(chuàng)建函數(shù):
pthread_create(pthread _t thread,const pthread_attr _t *attr,void*(*start_routine)(void*),void*arg);//arg 是給第三個(gè)傳的參數(shù)
2.線程的終止
線程在創(chuàng)建退出后,主線程必須進(jìn)行等待拿到其退出狀態(tài)。函數(shù)原型為:
int pthread_join(pthread_t thread,void ** retval)
這個(gè)函數(shù)是以阻塞方式進(jìn)行的。成功返回0,失敗返回錯(cuò)誤碼。
第一個(gè)終止方式:
在線程內(nèi)部直接return 或 用函數(shù) pthread_exit(void *retval);
第二個(gè)終止方式:
在線程內(nèi)部使用pthread _cancel(pthread_t thread);
thread 可以用函數(shù)pthread_t pthread_self(void)獲得當(dāng)前線程自己的id。
第三個(gè)終止方式:
在主函數(shù)內(nèi)部調(diào)用函數(shù) pthread _cancel(pthread_t thread);
三.線程代碼
1.只有一個(gè)子線程
//thread.c 1 #include<stdio.h> 2 #include<pthread.h> 3 4 void * thread_run(void *arg) 5 { 6 7 while(1) 9 { 10 printf("this is thread\n"); 11 sleep(1); 12 } 15 } 16 int main() 17 { 18 pthread_t tid; 19 int ret=pthread_create(&tid,NULL,thread_run,NULL); 21 while(1) 22 { 23 printf("this is main thread\n"); 24 sleep(2); 25 } 26 return 0; 27 }
運(yùn)行結(jié)果:
結(jié)果分析:
一直在運(yùn)行著,沒有終止。想要終止,調(diào)用終止函數(shù)。如下:
第一種終止方式:return 或者 pthread_exit()
//thread.c 1 #include<stdio.h> 2 #include<pthread.h> 3 4 void * thread_run(void *arg) 5 { 6 int count=5; 7 while(count-->0) 8 { 9 10 printf("this is thread\n"); 11 sleep(1); 12 } 13 //return (void*)1; 14 pthread_exit((void*)1); 15 } 16 int main() 17 { 18 pthread_t tid; 19 int ret=pthread_create(&tid,NULL,thread_run,NULL); 20 int count=10; 21 while(count-->0) 22 { 23 printf("this is main thread\n"); 24 sleep(2); 25 } 26 //pthread_cancel(tid); 27 void *status=0; 28 int retu=pthread_join(tid,&status); 29 if(retu==0) 30 { 31 printf("pthread_join: code:%d\n",(int)status); 32 33 } 34 return 0; 35 }
運(yùn)行結(jié)果:
分析:
當(dāng)在子線程中調(diào)用return 或者使用pthread_exit()函數(shù)終止子線程。主線程依然在跑。
第二種終止方式:pthread_cancel(pthread_self());
//thread.c 1 #include<stdio.h> 2 #include<pthread.h> 3 4 void * thread_run(void *arg) 5 { 6 int count=5; 7 while(count-->0) 8 { 9 10 printf("this is thread\n"); 11 sleep(1); 12 } 13 14 pthread_cancel(pthread_self()); 15 } 16 int main() 17 { 18 pthread_t tid; 19 int ret=pthread_create(&tid,NULL,thread_run,NULL); 20 int count=10; 21 while(count-->0) 22 { 23 printf("this is main thread\n"); 24 sleep(2); 25 } 26 27 void *status=0; 28 int retu=pthread_join(tid,&status); 29 if(retu==0) 30 { 31 printf("pthread_join: code:%d\n",(int)status); 32 33 } 34 return 0; 35 }
實(shí)驗(yàn)結(jié)果:
分析:
在子線程中調(diào)用pthread_cancel()終止自己,不過要通過pthread_self()來獲取自己的id。主線程還在跑,并且拿到子線程退出狀態(tài)。
第三種終止方式:
//thread.c 1 #include<stdio.h> 2 #include<pthread.h> 3 4 void * thread_run(void *arg) 5 { 6 int count=5; 7 while(count-->0) 8 { 9 10 printf("this is thread\n"); 11 sleep(1); 12 } 13 14 pthread_cancel(pthread_self()); 15 } 16 int main() 17 { 18 pthread_t tid; 19 int ret=pthread_create(&tid,NULL,thread_run,NULL); 20 int count=10; 21 while(count-->0) 22 { 23 printf("this is main thread\n"); 24 sleep(2); 25 } 26 27 void *status=0; 28 int retu=pthread_join(tid,&status); 29 if(retu==0) 30 { 31 printf("pthread_join: code:%d\n",(int)status); 32 33 } 34 return 0; 35 }
實(shí)驗(yàn)結(jié)果:
與上一個(gè)結(jié)果一樣,只不過是在主函數(shù)中調(diào)用pthread_cancel()來終止子線程。是被取消的,不是自己主動(dòng)的。
注:還有一種終止方式,在子線程中通過調(diào)用exit()函數(shù),此時(shí)進(jìn)程終止,因?yàn)檫M(jìn)程終止調(diào)用這個(gè)函數(shù)。一般不會(huì)使用其終止線程。將上述代碼thread_run()函數(shù)中用exit()函數(shù):
4 void * thread_run(void *arg) 5 { 6 int count=5; 7 while(count-->0) 8 { 9 10 printf("this is thread\n"); 11 sleep(1); 12 } 13 14 exit(1); 15 }
運(yùn)行結(jié)果:
當(dāng)子線程調(diào)用exit時(shí),進(jìn)程終止,也跑了5次。
2.創(chuàng)建多個(gè)線程:
41 void * thread1(void *arg) 42 { 43 int count=5; 44 while(count-->0) 45 { 46 47 printf("this is thread1: %d,thread_t :%u\n",(int)arg,pthread_self()); 48 sleep(1); 49 } 50 51 52 } 53 54 void * thread2(void *arg) 55 { 56 int count=5; 57 while(count-->0) 58 { 59 60 printf("this is thread2: %d,thread_t :%u\n",(int)arg,pthread_self()); 61 sleep(1); 62 } 63 void * thread2(void *arg) 64 { 65 int count=5; 66 while(count-->0) 67 { 68 int count=5; 69 while(count-->0) 70 { 71 72 printf("this is thread3: %d,thread_t :%u\n",(int)arg,pthread_self()); 73 sleep(1); 74 } 75 76 77 } 78 int main() 79 { 80 pthread_t tid1,tid2,tid3; 81 pthread_create(&tid1,NULL,thread1,(void*)1); 82 pthread_create(&tid2,NULL,thread2,(void*)2); 83 pthread_create(&tid3,NULL,thread3,(void*)3); 84 sleep(2); 85 pthread_cancel(tid3); 86 void* ret=NULL; 87 pthread_join(tid1,&ret); 88 pthread_join(tid2,&ret); 89 pthread_join(tid3,&ret); 90 return 0; }
運(yùn)行結(jié)果:
四.分離線程
在任意時(shí)間點(diǎn)上,線程是可結(jié)合的或者是分離的,默認(rèn)線程創(chuàng)建是可結(jié)合的。由于調(diào)用pthread_join()函數(shù)后,如果該線程沒有運(yùn)行結(jié)束,調(diào)用者會(huì)被阻塞,這時(shí)可在子線程中加入代碼:
pthread_detach(pthread_self());也可在主函數(shù)中調(diào)用pthread_detach(pthread_t thread);
文章標(biāo)題:線程的基本概念
文章路徑:http://www.rwnh.cn/article46/peohhg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、全網(wǎng)營(yíng)銷推廣、虛擬主機(jī)、、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)