国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網(wǎng)站 > 幫助中心 > 正文

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

2024-07-09 22:42:44
字體:
供稿:網(wǎng)友

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

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

那如果是把進(jìn)程換成線程的話,會怎么樣呢?假設(shè)主線程在子線程結(jié)束前就已經(jīng)退出,子線程會發(fā)生什么?

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

主線程先退出

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

#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終止主線程使其退出。運(yùn)行程序,可以發(fā)現(xiàn)在打印了一定數(shù)量的「main loops」之后程序就掛起了,但卻沒有退出。

主線程因?yàn)楸蛔泳€程終止了,所有沒有看到「main exit」的打印。子線程終止了主線程后進(jìn)入了死循環(huán)while中,所以程序看起來像掛起了。如果我們讓子進(jìn)程while循環(huán)中的打印語句生效再運(yùn)行就可以發(fā)現(xiàn)程序會一直打印「child loops」字樣。

主線程被子線程終止了,但他們所依賴的進(jìn)程并沒有退出,所以子線程依然正常運(yùn)轉(zhuǎn)。

主線程隨進(jìn)程一起退出

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

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;}

運(yùn)行上面的代碼,會發(fā)現(xiàn)程序在打印一定數(shù)量的「child loops」和一句「main exit」之后退出,并且在退出之前的最后一句打印是「main exit」。

按照他們的邏輯,你看,因?yàn)橹骶€程在打印完「main exit」后退出了,然后子線程也跟著退出了,所以隨后就沒有子線程的打印了。

但其實(shí)這里是混淆了進(jìn)程退出和線程退出的概念了。實(shí)際的情況是主線程中的main函數(shù)執(zhí)行完ruturn后彈棧,然后調(diào)用glibc庫函數(shù)exit,exit進(jìn)行相關(guān)清理工作后調(diào)用_exit系統(tǒng)調(diào)用退出該進(jìn)程。所以,這種情況實(shí)際上是因?yàn)檫M(jìn)程運(yùn)行完畢退出導(dǎo)致所有的線程也都跟著退出了,并非是因?yàn)橹骶€程的退出導(dǎo)致子線程也退出。

Linux線程模型

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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鸡东县| 湘乡市| 澎湖县| 女性| 乌兰察布市| 宁南县| 芦溪县| 南汇区| 抚松县| 元阳县| 阜新市| 鹤岗市| 清水县| 弥渡县| 鞍山市| 轮台县| 贵定县| 鄂州市| 宁河县| 七台河市| 马尔康县| 来安县| 濮阳县| 安溪县| 金湖县| 巴塘县| 濉溪县| 奈曼旗| 略阳县| 东阳市| 姚安县| 平陆县| 应城市| 新昌县| 海丰县| 天长市| 东乌| 寻甸| 夏河县| 三河市| 邳州市|