亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

簡單了解C語言中主線程退出對子線程的影響

2020-01-26 13:22:06
字體:
來源:轉載
供稿:網友

這篇文章主要介紹了簡單了解C語言中主線程退出對子線程的影響,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

對于程序來說,如果主進程在子進程還未結束時就已經退出,那么Linux內核會將子進程的父進程ID改為1(也就是init進程),當子進程結束后會由init進程來回收該子進程。

那如果是把進程換成線程的話,會怎么樣呢?假設主線程在子線程結束前就已經退出,子線程會發生什么?

在一些論壇上看到許多人說子線程也會跟著退出,其實這是錯誤的,原因在于他們混淆了線程退出和進程退出概念。實際的答案是主線程退出后子線程的狀態依賴于它所在的進程,如果進程沒有退出的話子線程依然正常運轉。如果進程退出了,那么它所有的線程都會退出,所以子線程也就退出了。

主線程先退出

先來看一個主線程先退出的例子:

#include <pthread.h>#include <unistd.h>#include <stdio.h>void* func(void* arg){  pthread_t main_tid = *static_cast<pthread_t*>(arg);  pthread_cancel(main_tid);  while (true)  {    //printf("child loops/n");  }  return NULL;}int main(int argc, char* argv[]){  pthread_t main_tid = pthread_self();  pthread_t tid = 0;  pthread_create(&tid, NULL, func, &main_tid);  while (true)  {    printf("main loops/n");  }  sleep(1);  printf("main exit/n");  return 0;}

把主線程的線程號傳給子線程,在子線程中通過pthread_cancel終止主線程使其退出。運行程序,可以發現在打印了一定數量的「main loops」之后程序就掛起了,但卻沒有退出。

主線程因為被子線程終止了,所有沒有看到「main exit」的打印。子線程終止了主線程后進入了死循環while中,所以程序看起來像掛起了。如果我們讓子進程while循環中的打印語句生效再運行就可以發現程序會一直打印「child loops」字樣。

主線程被子線程終止了,但他們所依賴的進程并沒有退出,所以子線程依然正常運轉。

主線程隨進程一起退出

之前看到一些人說如果主線程先退出了,子線程也會跟著退出,其實他們混淆了線程退出和進程退出的概念。下面這個例子代表了他們的觀點:

void* func(void* arg){  while (true)  {    printf("child loops/n");  }  return NULL;}int main(int argc, char* argv[]){  pthread_t main_tid = pthread_self();  pthread_t tid = 0;  pthread_create(&tid, NULL, func, &main_tid);  sleep(1);  printf("main exit/n");  return 0;}

運行上面的代碼,會發現程序在打印一定數量的「child loops」和一句「main exit」之后退出,并且在退出之前的最后一句打印是「main exit」。

按照他們的邏輯,你看,因為主線程在打印完「main exit」后退出了,然后子線程也跟著退出了,所以隨后就沒有子線程的打印了。

但其實這里是混淆了進程退出和線程退出的概念了。實際的情況是主線程中的main函數執行完ruturn后彈棧,然后調用glibc庫函數exit,exit進行相關清理工作后調用_exit系統調用退出該進程。所以,這種情況實際上是因為進程運行完畢退出導致所有的線程也都跟著退出了,并非是因為主線程的退出導致子線程也退出。

Linux線程模型

實際上,posix線程和一般的進程不同,在概念上沒有主線程和子線程之分(雖然在實際實現上還是有一些區分),如果仔細觀察apue或者unp等書會發現基本看不到「主線程」或者「子線程」等詞語,在csapp中甚至都是用「對等線程」一詞來描述線程間的關系。

在Linux 2.6以后的posix線程都是由用戶態的pthread庫來實現的。在使用pthread庫以后,在用戶視角看來,每一個tast_struct就對應一個線程(tast_struct原本是內核對應一個進程的結構),而一組線程以及他們所共同引用的一組資源就是進程。從Linux 2.6開始,內核有了線程組的概念,tast_struct結構中增加了一個tgid(thread group id)字段。getpid(獲取進程號)通過系統調用返回的也是tast_struct中的tgid,所以tgid其實就是進程號。而tast_struct中的線程號pid字段則由系統調用syscall(SYS_gettid)來獲取。

當線程收到一個kill致命信號時,內核會將處理動作施加到整個線程組上。為了應付「發送給進程的信號」和「發送給線程的信號」,tast_struct里面維護了兩套signal_pending,一套是線程組共用的,一套是線程獨有的。通過kill發送的致命信號被放在線程組共享的signal_pending中,可以任意由一個線程來處理。而通過pthread_kill發送的信號被放在線程獨有的signal_pending中,只能由本線程來處理。

關于線程與信號,apue有這么幾句:

每個線程都有自己的信號屏蔽字,但是信號的處理是進程中所有線程共享的。這意味著盡管單個線程可以阻止某些信號,但當線程修改了與某個信號相關的處理行為以后,所有的線程都必須共享這個處理行為的改變。這樣如果一個線程選擇忽略某個信號,而其他的線程可以恢復信號的默認處理行為,或者是為信號設置一個新的處理程序,從而可以撤銷上述線程的信號選擇。

如果信號的默認處理動作是終止該進程,那么把信號傳遞給某個線程仍然會殺掉整個進程。

例如一個程序a.out創建了一個子線程,假設主線程的線程號為9601,子線程的線程號為9602(它們的tgid都是9601),因為默認沒有設置信號處理程序,所以如果運行命令kill 9602的話,是可以把9601和9602這個兩個線程一起殺死的。如果不知道Linux線程背后的故事,可能就會覺得遇到靈異事件了。

另外系統調用syscall(SYS_gettid)獲取的線程號與pthread_self獲取的線程號是不同的,pthread_self獲取的線程號僅僅在線程所依賴的進程內部唯一,在pthread_self的man page中有這樣一段話:

Thread IDs are guaranteed to be unique only within a process. A thread ID may be reused after a terminated thread has been joined, or a detached thread has terminated.

所以在內核中唯一標識線程ID的線程號只能通過系統調用syscall(SYS_gettid)獲取。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美亚洲国产日韩2020| 亚洲三级 欧美三级| 国产成人久久久精品一区| 欧美大全免费观看电视剧大泉洋| 中文字幕国产日韩| 亚洲图片欧美日产| 2019国产精品自在线拍国产不卡| 精品国内自产拍在线观看| 欧美成人激情视频免费观看| 色yeye香蕉凹凸一区二区av| 国产精品大陆在线观看| 国产精品va在线播放我和闺蜜| 亚洲视频免费一区| 国产在线999| 成人激情在线播放| 国产91精品久久久久久久| 国产一区二区三区中文| 久久精品视频免费播放| 日韩有码片在线观看| 亚洲国产精品成人一区二区| 中文字幕日本精品| 日韩欧美中文第一页| 欧美国产日韩精品| 国产精品视频久久久久| 91精品免费久久久久久久久| 成人网欧美在线视频| 亚洲一区二区三区xxx视频| 欧美日韩成人黄色| 色爱av美腿丝袜综合粉嫩av| 欧美午夜精品久久久久久浪潮| 狠狠综合久久av一区二区小说| 国产综合在线视频| 欧美日韩国产中文精品字幕自在自线| 国产精品夫妻激情| 亚洲欧美精品中文字幕在线| 久久亚洲精品一区二区| 亚洲高清一二三区| 欧美巨乳在线观看| 日韩精品久久久久久福利| 91国内揄拍国内精品对白| 国产日韩欧美夫妻视频在线观看| 最近的2019中文字幕免费一页| 国产日本欧美一区二区三区在线| 国产va免费精品高清在线| 日本韩国欧美精品大片卡二| 色小说视频一区| 性欧美暴力猛交69hd| 热99精品只有里视频精品| 精品国产91久久久久久老师| 91久久精品在线| 亚洲国产欧美一区| 精品视频在线播放| 久久777国产线看观看精品| 国产精品久久久久久久久| 亚洲国产福利在线| 日韩美女视频免费在线观看| 97久久久免费福利网址| 国产精品91免费在线| 色yeye香蕉凹凸一区二区av| 国产成人一区二区三区| 欧美在线视频网站| 成人h猎奇视频网站| 亚洲va久久久噜噜噜久久天堂| 91久久精品国产| 情事1991在线| 91免费精品视频| 亚洲国产精品久久久久秋霞蜜臀| 国产精品偷伦免费视频观看的| 亚洲国产黄色片| 久久香蕉精品香蕉| 久久久久久久久久久人体| 一本色道久久88精品综合| 国产欧美日韩最新| 日韩高清电影好看的电视剧电影| 精品国产31久久久久久| 欧美日韩亚洲高清| 久久久久久久av| 色悠悠国产精品| 亚洲成人免费网站| 一本色道久久综合亚洲精品小说| 国产伊人精品在线| 亚洲影院在线看| 日韩成人在线视频网站| 成人中心免费视频| 亚洲欧美综合v| 亚洲视频国产视频| 国产精品大陆在线观看| 亚洲免费一级电影| 国产精品吴梦梦| 日韩欧美国产网站| 欧美精品久久久久| 久久视频在线播放| 国产精品免费久久久久影院| 国产精自产拍久久久久久蜜| 国产精品美女av| 日本高清视频精品| 日韩av123| 一道本无吗dⅴd在线播放一区| 久久久噜噜噜久久| 色一情一乱一区二区| 亚洲va欧美va在线观看| 成人在线激情视频| 亚洲精品久久久久| 久久人人爽人人爽爽久久| 国内揄拍国内精品| 精品欧美激情精品一区| 精品高清美女精品国产区| 亚洲少妇中文在线| 成人免费看吃奶视频网站| 亚洲精品在线观看www| 97免费视频在线播放| 裸体女人亚洲精品一区| 国产z一区二区三区| 人妖精品videosex性欧美| 亚洲91精品在线观看| 日本一欧美一欧美一亚洲视频| 亚洲理论在线a中文字幕| 久久免费视频网| 精品女厕一区二区三区| 欧美性猛交xxxx富婆弯腰| 久久噜噜噜精品国产亚洲综合| 日韩经典中文字幕| 欧美大片欧美激情性色a∨久久| 91av在线播放| 欧美国产精品日韩| 国产欧洲精品视频| 精品久久久国产精品999| 欧美日韩午夜激情| 久久久久久国产精品| 日韩高清中文字幕| 亚州欧美日韩中文视频| 亚洲性线免费观看视频成熟| 国产精品观看在线亚洲人成网| 大荫蒂欧美视频另类xxxx| 久久精品国产清自在天天线| 亚洲成色777777在线观看影院| 7777kkkk成人观看| 欧美日韩免费在线观看| 久久99精品国产99久久6尤物| 国产免费久久av| 亚洲欧洲中文天堂| 日韩成人在线视频| 91色精品视频在线| 亚洲免费视频网站| 不卡伊人av在线播放| 日本精品va在线观看| 疯狂做受xxxx欧美肥白少妇| 久久精品国产亚洲一区二区| 中文字幕9999| 国产成人精品免费视频| 日韩在线欧美在线| 国产精品久久久久久亚洲影视| 精品在线观看国产| 亚洲精品日韩久久久| 亚洲永久在线观看| 国产精品一区二区久久久| 欧美在线免费观看| 九九热视频这里只有精品| 国产日韩专区在线| 久久久久久午夜| 国产女精品视频网站免费| 国产va免费精品高清在线| 亚洲美女又黄又爽在线观看| 国产精品一区二区三区在线播放|