如何實(shí)現(xiàn)Linux多線程編程

這篇文章主要介紹“如何實(shí)現(xiàn)Linux多線程編程”,在日常操作中,相信很多人在如何實(shí)現(xiàn)Linux多線程編程問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”如何實(shí)現(xiàn)Linux多線程編程”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

啟東ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!

一、多線程 VS 多進(jìn)程

和進(jìn)程相比,線程有很多優(yōu)勢(shì)。在Linux系統(tǒng)下,啟動(dòng)一個(gè)新的進(jìn)程必須分配給它獨(dú)立的地址空間,建立眾多的數(shù)據(jù)表來(lái)維護(hù)代碼段和數(shù)據(jù)。而運(yùn)行于一個(gè)進(jìn)程中的多個(gè)線程,他們之間使用相同的地址空間。正是這樣,同一進(jìn)程下的線程之間共享數(shù)據(jù)空間,數(shù)據(jù)可以相互使用,并且線程間切換也要更快些,可以更有效的利用CPU。

二、程序設(shè)計(jì)

[注] 頭文件<pthread.h> 編譯時(shí)要加載動(dòng)態(tài)庫(kù) libpthread.a,使用 -lpthread
 
1、創(chuàng)建線程
2、等待線程
3、關(guān)閉線程
4、退出清除
 
1、創(chuàng)建線程

代碼如下:


        int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, void *(*start_rtn)(void), void *arg)


tidp為線程id,是函數(shù)分配的值,所以要傳一個(gè) pthread_t 的地址。
attr線程屬性,通常為空。
start_rtn為線程要執(zhí)行的函數(shù),返回值為空指針,參數(shù)為后面的*arg
若成功則返回0,否則返回出錯(cuò)編號(hào)。
 
例:

代碼如下:


#include<stdio.h>
#include<pthread.h></p> <p>void *func1(void *arg){        //原函數(shù)聲明
       int i;
       for(i=0;i<5;i++){
               printf("this is func1! The num is %d\n",*(int*)arg);    //將空指針轉(zhuǎn)換為int型指針
               sleep(1);
       }
}</p> <p>void *func2(int *m){ //自定義類型聲明,也可以定義非指針類型,但是在create時(shí)會(huì)有警告,因?yàn)榉堑刂凡⒉荒芨淖儌魅氲闹?br/>       int i;
       for(i=0;i<5;i++){
               printf("this is func2! The num is %d\n",*m);
               (*m)++;
               sleep(1);
       }
}</p> <p>int main(){
       pthread_t id1,id2;
       int num = 5;
       int *p = &num;
       if(pthread_create(&id1,NULL,(void *)func1,(void *)p) != 0){
               printf("thread1 create error!\n");
               return -1;
       }
       if(pthread_create(&id2,NULL,(void *)func2,&num) != 0){
               printf("thread2 create error!\n");
               return -1;
       }
       pthread_join(id1,NULL);     //等待線程結(jié)束  
       pthread_join(id2,NULL);
       printf("Running complete!\n");
       return 0;</p> <p>
}

運(yùn)行結(jié)果:

代碼如下:


[fsy@localhost process]$ gcc thC.c -o thC -lpthread -g
[fsy@localhost process]$ ./thC
this is func2! The num is 5
this is func1! The num is 6
this is func2! The num is 6
this is func1! The num is 7
this is func2! The num is 7
this is func1! The num is 8
this is func2! The num is 8
this is func1! The num is 9
this is func2! The num is 9
this is func1! The num is 10
Running complete!
[fsy@localhost process]$


2、等待線程

[注]當(dāng)調(diào)用pthread_create函數(shù)時(shí),線程并沒(méi)有開始執(zhí)行,主進(jìn)程應(yīng)有等待,比如用sleep,或者用更專業(yè)的函數(shù):pthread_join

代碼如下:


   int pthread_join(pthread_t tid, void **rval_ptr)


調(diào)用函數(shù)可以阻塞調(diào)用線程,直到指定的線程終止。
tid為等待退出線程的id,rval_ptr為函數(shù)的返回值。是指向指針的指針,可以置空。
 
例:

代碼如下:


#include<stdio.h>
#include<pthread.h>
#include<stdlib.h></p> <p>void *func(int *p){
       int *num=(int *)malloc(sizeof(int));     //必須動(dòng)態(tài)創(chuàng)建,原因可以參考我動(dòng)態(tài)分配內(nèi)存的博客
       printf("Please input the number: ");
       scanf("%d",num);
       return (void *)num;              //類型是pthread_create的參數(shù)規(guī)定的
}</p> <p>int main(){
       pthread_t pth;
       void *a;
       if(pthread_create(&pth,NULL,(void *)func,NULL) != 0){
               printf("create thread error!\n");
               return 1;
       }
       pthread_join(pth,&a);          //指向空指針的指針
       printf("get the num from the thread, it's %d\n",*(int *)a);
       return 0;
}

3、終止線程

線程終止有以下三種方式:

1、線程從函數(shù)中返回
2、線程可以別其他函數(shù)終止
3、線程自己調(diào)用pthread_exit函數(shù)

代碼如下:


void pthread_exit(void *rval_ptr)


rval_ptr為線程退出返回值的指針,即函數(shù)返回值。

4、退出清除

代碼如下:


      void pthread_cleanup_push(void (*rtn)(void*), void *arg)


rtn為清除函數(shù),arg是清除函數(shù)的參數(shù)

代碼如下:


void pthread_cleanup_pop(int execute)


當(dāng)execute 非0時(shí)執(zhí)行清除函數(shù)。為0時(shí)不執(zhí)行。

從pthread_cleanup_push的調(diào)用點(diǎn)到pthread_cleanup_pop之間的程序段中,如果有終止進(jìn)程的動(dòng)作,如調(diào)用pthread_exit或異常終止(不包括return),就會(huì)執(zhí)行pthread_cleanup_push()所指定的清理函數(shù)。多個(gè)嵌套匹配時(shí),就近匹配。
 
例:

代碼如下:


#include<stdio.h>
#include<pthread.h></p> <p>void *clean(char *argv){
       printf("clean is called by %s\n",argv);
       return NULL;
}
void *func1(void *argv){
       printf("welcome enter the func1!\n");
       pthread_cleanup_push((void*)clean,"the first time call!");
       pthread_cleanup_push((void*)clean,"the second time call!");
       if(argv){
               return (void *)1;            //第二次運(yùn)行將此句注掉
       }
       pthread_cleanup_pop(0);
       pthread_cleanup_pop(1);
       return (void *)0;
}</p> <p>void *func2(void *argv){
       sleep(1);             //兩個(gè)線程運(yùn)行先后不確定
       printf("welcome enter the func2!\n");
       pthread_cleanup_push((void*)clean,"the first time call!");
       pthread_cleanup_push((void*)clean,"the second time call!");
       if(argv){
               pthread_exit(NULL);
       }
       pthread_cleanup_pop(0);
       pthread_cleanup_pop(0);
       return (void *)0;
}</p> <p>
int main(){
       pthread_t tid1,tid2;
       if(pthread_create(&tid1,NULL,(void *)func1,(void *)1) != 0){
               printf("thread1 create error!\n");
               return 1;
       }</p> <p>         if(pthread_create(&tid2,NULL,(void *)func2,(void *)1) != 0){
               printf("thread2 create error!\n");
               return 1;
       }
       pthread_join(tid1,NULL);
       pthread_join(tid2,NULL);
       return 0;
}

運(yùn)行結(jié)果:

代碼如下:


[fsy@localhost process]$ gcc thClean.c -o thclean -lpthread
[fsy@localhost process]$ ./thclean
welcome enter the func1!
welcome enter the func2!
clean is called by the second time call!          //此處先2后1
clean is called by the first time call!
[fsy@localhost process]$ vim thClean.c
[fsy@localhost process]$ gcc thClean.c -o thclean -lpthread
[fsy@localhost process]$ ./thclean
welcome enter the func1!
clean is called by the first time call!          //second已經(jīng)被pop
welcome enter the func2!
clean is called by the second time call!
clean is called by the first time call!
[fsy@localhost process]$

到此,關(guān)于“如何實(shí)現(xiàn)Linux多線程編程”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

網(wǎng)站標(biāo)題:如何實(shí)現(xiàn)Linux多線程編程
本文來(lái)源:http://bm7419.com/article44/jdgdhe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)公司、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站改版、網(wǎng)站營(yí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í)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站