日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

pthread_join函数

發(fā)布時(shí)間:2023/11/30 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pthread_join函数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

int pthread_join(pthread_t thread, void **retval);

作用:阻塞等待線程退出,獲取線程退出狀態(tài)。其作用對(duì)應(yīng)進(jìn)程中 waitpid() 函數(shù)。

成功:0;失敗:錯(cuò)誤號(hào) ??strerror函數(shù)

參數(shù):thread:線程ID (注意:不是指針);retval:存儲(chǔ)線程結(jié)束狀態(tài)。

對(duì)比記憶:在wait回收子進(jìn)程時(shí),子進(jìn)程exit或return返回的值即為status的值(int類型),wait函數(shù)第一個(gè)形參為回收進(jìn)程的pid,第二個(gè)形參為&status(int *類型指針);對(duì)于回收子線程時(shí),子線程退出的值(pthread_exit函數(shù),或return返回的值)都為void *類型,則pthread_join函數(shù)的第一個(gè)形參為線程ID(pthread_t類型),第二個(gè)形參為void **類型。

調(diào)用該函數(shù)的線程將掛起等待,直到idthread的線程終止。thread線程以不同的方法終止,通過(guò)pthread_join得到的終止?fàn)顟B(tài)是不同的,總結(jié)如下:

  • 如果thread線程通過(guò)return返回,retval所指向的單元里存放的是thread線程函數(shù)的返回值(即void *指針);
  • 如果thread線程被別的線程調(diào)用pthread_cancel異常終止掉,retval所指向的單元里存放的是常數(shù)PTHREAD_CANCELED。
  • 如果thread線程是自己調(diào)用pthread_exit終止的,retval所指向的單元存放的是傳給pthread_exit的參數(shù)(即void *指針),其實(shí)1與3是等效的。
  • 如果對(duì)thread線程的終止?fàn)顟B(tài)不感興趣,可以傳NULL給retval參數(shù)。
  • 對(duì)應(yīng)于僵尸進(jìn)程,也是存在僵尸線程。因此,在線程結(jié)束時(shí),也需要對(duì)線程進(jìn)行回收以釋放僵尸線程所占用的資源。對(duì)進(jìn)程的回收有區(qū)別的就是,一個(gè)進(jìn)程中的所有線程都是可以互相回收的,即不是只能由主控線程回收子線程,兄弟線程之間也可以回收。一次pthread_join只能回收一個(gè)線程。回收線程時(shí)也可以不關(guān)心線程結(jié)束時(shí)的狀態(tài),pthread_join函數(shù)的參數(shù)傳NULL即可,此時(shí)不關(guān)心線程結(jié)束時(shí)的狀態(tài),只是將其回收并釋放線程所占用的資源。

    //循環(huán)創(chuàng)建n個(gè)子線程,并回收這n個(gè)子線程

    #include <stdio.h> #include <pthread.h> #include <string.h> #include <unistd.h> #include <stdlib.h>typedef struct {int a;char b;char str[10]; }exit_t; //返回值為一個(gè)結(jié)構(gòu)體void *ftn( void *arg ) {int s;exit_t *retval; //retval的地址在棧空間,但是retval本身卻位與堆空間(heap),malloc所分配的。retval=(exit_t *)malloc( sizeof(exit_t) ); //必須用malloc分配,不能用線程棧空間s=(int)arg; //注意只能傳值,不能傳地址(用于判別是哪個(gè)線程)if( s<=1 ){retval->a=10;retval->b='a';strcpy(retval->str,"zsx");}if( s>1 && s<=3 ){retval->a=20;retval->b='b';strcpy(retval->str,"rgf");}if( s>3 ){retval->a=30;retval->b='c';strcpy(retval->str,"zy");}printf("I am %dth thread, and my ID is %lu.\n",s+1,pthread_self( ));pthread_exit((void *)retval); //或者 return (void *)retval; 兩者等價(jià)! }int main(int argc, char *argv[ ]) {int n=5, i, ret;if( argc==2 )n=atoi(argv[1]);pthread_t tid[n];for(i=0;i<n;i++){ret=pthread_create(&tid[i],NULL,ftn,(void *)i); //注意只能傳值,不能傳地址,因?yàn)榈刂穼?duì)應(yīng)的i值會(huì)變化if( ret!=0){fprintf(stderr,"pthread_create error: %s\n",strerror(ret));exit(1);}}for(i=0;i<n;i++) //回收每個(gè)子線程{exit_t *re; //re位于主控線程的棧空間,但是re本身的值為子線程傳給它的值。ret=pthread_join( tid[i],(void **)&re);if( ret!=0){fprintf(stderr,"pthread_join error: %s\n",strerror(ret));exit(1);}printf("the %dth thread: a=%d, b=%c, str=%s.\n",i+1,re->a,re->b,re->str);free(re); //注意必須釋放malloc分配的空間,防止內(nèi)存泄漏re = NULL; //置空,防止使用幽靈指針}printf("In main: the PID is %d, and the TID is %lu.\n",getpid( ),pthread_self( ));pthread_exit((void *)1); }

    [root@localhost 01_pthread_test]# ./ptrd_join

    I am 4th thread, and my ID is 4124101440.

    I am 2th thread, and my ID is 4140886848.

    I am 1th thread, and my ID is 4149279552.

    I am 5th thread, and my ID is 4115708736.

    I am 3th thread, and my ID is 4132494144.

    the 1th thread: a=10, b=a, str=zsx.

    the 2th thread: a=10, b=a, str=zsx.

    the 3th thread: a=20, b=b, str=rgf.

    the 4th thread: a=20, b=b, str=rgf.

    the 5th thread: a=30, b=c, str=zy.

    In main: the PID is 10415, and the TID is 4151490816.

    分析討論:

  • 強(qiáng)調(diào)一點(diǎn):子線程的返回值為void *指針,其指針?biāo)赶虻牡刂繁仨毼挥谌謪^(qū)或者malloc分配的空間,不能位于用戶棧空間;
  • 之所以子線程的返回值以及線程函數(shù)ftn的形參都要為void *類型,這是為了方便可以傳遞任何數(shù)據(jù)類型;
  • 其實(shí)回收子線程的返回值的方式有很多種:a.第一種方式:上述程序中,exit_t *retval; 然后直接返回retval這個(gè)地址給主控線程,但是地址不能是用戶棧空間,因此用malloc函數(shù)分配空間后,再賦值返回;b.第二種方式:也可以exit_t retval,即直接返回retval本身這個(gè)值,即return (void *)retval; 主控線程中:exit_t *re; (exit_t)re即可,但是不建議這樣做,兼容性不高。這種方法類似于上面的i傳參方式;c.第三種方式:還是按值傳遞,即利用主控線程中的pthread_create函數(shù)中的最后一個(gè)參數(shù),將值傳給子線程,然后讓子線程返回回來(lái),即:主控線程: exit_t *re=(exit_t *)malloc( sizeof(exit_t) ), 然后(void *)re作為其最后一個(gè)參數(shù)傳遞給子線程的arg參數(shù),則子線程中:(exit_t *)arg,然后給arg賦值,最后(void *)arg返回即可!
  • 注意在線程函數(shù)中:pthread_exit((void *)retval);不能寫為:pthread_exit((void *)&retval);? 同樣的錯(cuò)誤,即這樣相當(dāng)于傳遞的是子線程用戶棧空間的地址。
  • 總結(jié)

    以上是生活随笔為你收集整理的pthread_join函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产精品久久久久久免费 | 超碰97在线看 | 在线免费观看一区二区三区 | 免费精品视频 | 91久久爱 | 女人叫床高潮娇喘声录音mp3 | 男人天堂影院 | 秋霞毛片少妇激情免费 | 日韩av自拍偷拍 | 国产黄色精品 | 色老头一区二区三区在线观看 | eeuss鲁丝片一区二区三区 | 九九热最新网址 | 亚洲综合一二三区 | 隣の若妻さん波多野结衣 | 国产经典一区二区三区 | 亚洲女同一区 | 欧美人与性禽动交精品 | 抱着老师的嫩臀猛然挺进视频 | 99色网站| 成人免费看片入口 | 有码av在线 | 潘金莲一级淫片aaaaa | 久久免费久久 | 国产a国产 | 亚洲综合成人亚洲 | 青青草久 | 成人精品久久久午夜福利 | 欧美中文字幕在线播放 | 99久久一区二区 | 雪花飘电影在线观看免费高清 | 在线中文字幕观看 | 国产第一草草影院 | 免费毛片观看 | 日日噜噜噜夜夜爽爽狠狠视频97 | 91在现看 | 亚洲精品系列 | 久久欧美 | 性感美女被草 | 国产精品美女毛片真酒店 | 成人在线免费电影 | 国产成人中文字幕 | 中文字幕欧美视频 | 亚洲一区二区三区四区在线 | 日韩精品在线观看一区二区 | 激情综合激情五月 | 日本少妇高潮抽搐 | 成熟妇人a片免费看网站 | 99视频久| 91成人在线 | 久久亚洲综合 | 日韩电影在线观看中文字幕 | 亚洲午夜精品久久 | 亚洲一区二区播放 | 国产麻豆成人传媒免费观看 | 国产精品老女人 | 97国产在线播放 | 国产第99页 | 免费三级黄 | 欧美成人视 | 插吧插吧综合网 | 国产精品人人人人 | 精品少妇人妻av免费久久洗澡 | 高潮毛片又色又爽免费 | 毛片毛片毛片毛片毛片毛片毛片 | 色人阁视频| 日韩欧美亚洲一区二区三区 | 亚洲精品在线中文字幕 | 国产天天射 | 91精品久久久久久久久中文字幕 | 日本不卡视频在线播放 | 女女综合网 | 久久久久成人网 | xxxx视频在线观看 | 澳门久久 | 久久久久久无码精品大片 | 在线观看69 | 国产女主播在线 | 久久久噜噜噜久久久 | 亚洲精品伊人 | 高潮毛片无遮挡 | 美女色呦呦| 久操视频精品 | 大粗鳮巴久久久久久久久 | 久久高清内射无套 | 亚洲六月丁香色婷婷综合久久 | 可以直接观看的av | 日本韩国欧美在线 | 欧美成人午夜电影 | 男人的天堂免费 | 亚洲大尺度视频 | 成人免费影视网站 | 销魂奶水汁系列小说 | 精品久久无码中文字幕 | 久久亚洲熟女cc98cm | 福利在线视频导航 | 秘密基地电影免费版观看国语 | 午夜寂寞福利 | 亚洲一区二区三区婷婷 |