我们在一个线程中经常会创建另外的新线程,如果主线程退出,会不会影响它所创建的新线程呢?下面就来讨论一下。

1、  主线程等待新线程先结束退出,主线程后退出。正常执行。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h> pthread_t ntid;//线程ID void printids(const char *s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
printf("%s pid %u tid %u (0x%x)\n",s,(unsigned int)pid,
(unsigned int)tid,(unsigned int)tid);
} void *thrfun(void *arg){
//sleep(1);//使得主线程先退出
printids("new thread"); return ((void *)0);
} int main(){
int err;
err = pthread_create(&ntid,NULL,thrfun,NULL); if(err != 0)
perror("pthread_create");
printids("main thread"); sleep(1);//等待新线程先结束 exit(0);
}

运行结果:

huangcheng@ubuntu:~$ ./a.out
main thread pid 2344 tid 3077813952 (0xb773b6c0)
new thread pid 2344 tid 3077811056 (0xb773ab70)

2、  进程先退出,新线程也会立即退出,系统清除所有资源。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h> pthread_t ntid;//线程ID void printids(const char *s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
printf("%s pid %u tid %u (0x%x)\n",s,(unsigned int)pid,
(unsigned int)tid,(unsigned int)tid);
} void *thrfun(void *arg){
sleep(1);//使得主线程先退出
printids("new thread"); return ((void *)0);
} int main(){
int err;
err = pthread_create(&ntid,NULL,thrfun,NULL); if(err != 0)
perror("pthread_create");
printids("main thread"); //sleep(1);//等待新线程先结束 exit(0);
}

运行结果:

huangcheng@ubuntu:~$ ./a.out
main thread pid 2366 tid 3077641920 (0xb77116c0)

可以发现主线程退出后所创建的新线程也停止运行了。

3、如果主线程调用了pthread_exit,那么它退出了,子线程也不会退出。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h> pthread_t ntid;//线程ID void printids(const char *s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
printf("%s pid %u tid %u (0x%x)\n",s,(unsigned int)pid,
(unsigned int)tid,(unsigned int)tid);
} void *thrfun(void *arg){
sleep(1);//使得主线程先退出
printids("new thread"); return ((void *)0);
} int main(){
int err;
err = pthread_create(&ntid,NULL,thrfun,NULL); if(err != 0)
perror("pthread_create");
printids("main thread"); //sleep(1);//等待新线程先结束
pthread_exit(NULL); // exit(0);
}

运行结果:

huangcheng@ubuntu:~$ ./a.out
main thread pid 2385 tid 3077768896 (0xb77306c0)
new thread pid 2385 tid 3077766000 (0xb772fb70)

POSIX标准定义:

When you program with POSIX Threads API,there is one thing about pthread_exit() that you may ignore for mistake. Insubroutines that complete normally, there is nothing special you have to dounless you want to pass a return code back using pthread_exit(). The completionwon't affect the other threads which were created by the main thread of thissubroutine. However, in main(), when the code has been executed to the end,there could leave a choice for you. If you want to kill all the threads thatmain() created before, you can dispense with calling any functions. But if you want to keep the process and all the other threadsexcept for the main thread alive after the exit of main(), then you can call pthread_exit()to realize it. And any files opened inside the main thread will remain openafter its termination.

按照POSIX标准定义,当主线程在子线程终止之前调用pthread_exit()时,子线程是不会退出的。

注意:这里在main函数中调用pthread_exit()只会是主线程退出,而进程并未退出。因此新线程继续执行而没有退出。

我们可以在return 0;这条语句前面添加一条输出语句printf(“Mainthread has exited!\n”);来进行测试,输出结果不发生任何变化,说明这条语句没有被执行到。也就说明进程并未退出。

因此:

     一个线程的退出不会影响另外一个线程。但是进程结束,所有线程也就结束了,所有资源会被回收。

我们可以再写一个程序来进行验证:

4、在创建的新线程B中再次创建新线程C,那么如果B先退出,那么C将会继续执行而不会退出。

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h> pthread_t ntid;//线程ID void printids(const char *s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
printf("%s pid %u tid %u (0x%x)\n",s,(unsigned int)pid,
(unsigned int)tid,(unsigned int)tid);
} void *thrfun2(void *arg){
sleep(1);//使得创建它的主线程先退出
printids("new thread of the new thread"); return ((void *)0);
} void *thrfun(void *arg){
sleep(1);//使得主线程先退出
printids("new thread");
int err;
err = pthread_create(&ntid,NULL,thrfun2,NULL); if(err != 0)
perror("pthread_create"); return ((void *)0);
} int main(){
int err;
err = pthread_create(&ntid,NULL,thrfun,NULL); if(err != 0)
perror("pthread_create");
printids("main thread"); //sleep(1); pthread_exit(NULL);
}

运行结果:

huangcheng@ubuntu:~$ ./a.out
main thread pid 2413 tid 3077912256 (0xb77536c0)
new thread pid 2413 tid 3077909360 (0xb7752b70)
new thread of the new thread pid 2413 tid 3069516656 (0xb6f51b70)

UNIX环境高级编程——主线程与子线程的退出关系的更多相关文章

  1. (转)C#/.NET主线程与子线程之间的关系

    一般 一个应用程序就对应一个进程,一个进程可有一个或多个线程,而一般有一个主线程.       有的博客上说“至少一个主线程”,这一说法持有怀疑         主线程与子线程之间的关系        ...

  2. C#/.NET主线程与子线程之间的关系

    以前一直没有在程序中写过总结,再翻开程序时却不知所云,所以我决定写总结        一般 一个应用程序就对应一个进程,一个进程可有一个或多个线程,而一般有一个主线程.       有的博客上说“至少 ...

  3. Unix 环境高级编程

    UNIX 环境高级编程 本书描述了UNIX系统的程序设计接口--系统调用接口和标准C库提供的很多函数. 与大多数操作系统一样,Unix为程序员运行提供了大量的服务--打开文件,读文件,启动一个新程序, ...

  4. (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  5. multiple definition of `err_sys' 《UNIX环境高级编程》

    本文地址:http://www.cnblogs.com/yhLinux/p/4079930.html 问题描述: [点击此处直接看解决方案] 在练习<UNIX环境高级编程>APUE程序清单 ...

  6. unix环境高级编程基础知识之第二篇(3)

    看了unix环境高级编程第三章,把代码也都自己敲了一遍,另主要讲解了一些IO函数,read/write/fseek/fcntl:这里主要是c函数,比较容易,看多了就熟悉了.对fcntl函数讲解比较到位 ...

  7. (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  8. (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  9. (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

随机推荐

  1. Python Selenium 之数据驱动测试

    数据驱动模式的测试好处相比普通模式的测试就显而易见了吧!使用数据驱动的模式,可以根据业务分解测试数据,只需定义变量,使用外部或者自定义的数据使其参数化,从而避免了使用之前测试脚本中固定的数据.可以将测 ...

  2. vue.js-路由

    1:编写router.js   import Router from "vue-router" import Vue from "vue" import rou ...

  3. vue通过id从列表页跳转到对应的详情页

    1. 列表页:列表页带id跳转到详情页 详情页:把id传回到后台就可以获取到数据了 2.列表页跳转到详情页并更改详情页的标题 列表页:带id和页面标题的typeid跳转到详情页 详情页:在html绑定 ...

  4. No package tomcatX available. 解决办法

    当一个新的linux系统到手时,就要开始部署相关软件等等,有时候可能遇到无法安装的情况. 例如yum install tomcat7,在centos下无法安装,因为tomcat不再yum里面,怎么办呢 ...

  5. Linux完全卸载Oracle的操作步骤

    卸载步骤如下:1.运行$ORACLE_HOME/bin/localconfig delete2.rm -rf $ORACLE_BASE/*3.rm -f /etc/oraInst.loc etc/or ...

  6. Hive中yyyymmdd和yyyy-mm-dd日期之间的切换

    以2017-12-05和20171205相互转换为例说明 方法1: from_unixtime+ unix_timestamp --20171205转成2017-12-05 ','yyyymmdd') ...

  7. Node.js 工具模块

    在 Node.js 模块库中有很多好用的模块.接下来我们为大家介绍几种常用模块的使用: 序号 模块名 & 描述 1 OS 模块 提供基本的系统操作函数. 2 Path 模块提供了处理和转换文件 ...

  8. 王家林人工智能AI课程大纲和电子书 - 老师微信13928463918

    **3980元团购原价19800元的AI课程,团购请加王家林老师微信13928463918. 基于王家林老师独创的人工智能"项目情景投射"学习法,任何IT人员皆可在无需数学和Pyt ...

  9. Latex:简介及安装

    http://blog.csdn.net/pipisorry/article/details/53998352 LaTex是一个排版工具,功能强大.它是一个"所想即所得"的工具,你 ...

  10. 初识mybatis(二)

    上篇博客我们介绍通过Java代码来创建mybatis的配置文件,港真,这种方式看起来有意思实际在开发中用的并不多,mybatis的配置还是以xml配置为主,本文我们就来看看如何通过xml文件来配置my ...