记得以前刚接触多线程编程时,作为一个新手遇到的一个问题就是:我创建的子线程为什么没有跑起来?如以下最简单的一个程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>void *thread_function(void *arg);
char message[] = "THREAD_TEST";
struct test
{int a;int b;int c;
};
struct test outpara;int main()
{int res;pthread_t a_thread;void *thread_result;struct test para = {.a = 10,.b = 20,.c = 30,};res = pthread_create(&a_thread, NULL, thread_function, (void *)&para);if(res != 0){perror("Pthread_create");exit(EXIT_FAILURE);}printf("the thread has finish, return %d\n", ((struct test*)thread_result)->a);exit(EXIT_SUCCESS);
}void *thread_function(void *arg)
{struct test inpara = *(struct test*)arg;printf("thread is running, the parameter is %d, %d, %d\n", inpara.a,inpara.b, inpara.c);sleep(300);outpara.a = 100, outpara.b = 200,outpara.c = 300,pthread_exit(&outpara);
}

执行结果却是诡异的:

大部分情况子线程就没有执行起来,偶尔会有一次子线程执行了。这是为什么呢?这是因为进程退出时,其创建的子线程都会被终止。那有没有办法让主线程退出时,子线程继续执行呢?有一个函数可以实现:pthread_exit()。

我们 man pthread_exit 可以看到:

pthread_exit 函数会终止调用线程,但在线程终止时,进程共享资源不会被释放,只有进程中的最后一个线程终止时,进程共享资源才会释放。

#include "Thread.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/syscall.h>
#include <signal.h>namespace CurrentThread
{__thread int tCachedTid = 0;void cacheTid(){if(tCachedTid == 0){printf("first time get tid\n");tCachedTid = (int)syscall(SYS_gettid);}}inline int tid(){if(tCachedTid == 0){cacheTid();}return tCachedTid;}
}class CMyThread: public CThread
{
public:CMyThread();~CMyThread();virtual void threadProc();
};CMyThread::CMyThread(): CThread("myThread")
{}CMyThread::~CMyThread()
{}void CMyThread::threadProc()
{int count = 5;while(count--){sleep(1);printf("in CMyThread, threadID = %d\n", CurrentThread::tid());}pthread_exit(NULL);
}int main()
{CMyThread *myThread = new CMyThread();myThread->createThread();printf("exit main thread!\n");pthread_exit(NULL);return 0;
}

执行结果:

若是主线程调用 pthread_exit() 进行退出,则其创建的子线程会继续执行,直到整个进程终止。假如主线程用 return 或 exit() 进行退出,则整个进程就退出了,子线程可能还没来得及执行。

那如果子线程崩溃了,整个进程会结束吗? 如我在子线程里对NULL指针进行操作,这样会产生一个 SIGSEGV 信号:

#include "Thread.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/syscall.h>
#include <signal.h>namespace CurrentThread
{__thread int tCachedTid = 0;void cacheTid(){if(tCachedTid == 0){printf("first time get tid\n");tCachedTid = (int)syscall(SYS_gettid);}}inline int tid(){if(tCachedTid == 0){cacheTid();}return tCachedTid;}
}class CMyThread: public CThread
{
public:CMyThread();~CMyThread();virtual void threadProc();
};CMyThread::CMyThread(): CThread("myThread")
{}CMyThread::~CMyThread()
{}void CMyThread::threadProc()
{int count = 5;while(count--){sleep(1);printf("in CMyThread, threadID = %d\n", CurrentThread::tid());}char *p = NULL;memcpy(p, "test", 4);pthread_exit(NULL);
}int main()
{CMyThread *myThread = new CMyThread();myThread->createThread();sleep(10);printf("exit main thread!\n");return 0;
}

可以看到进程结束了,没跑用例前我以为子线程崩溃主线程不会有影响,但是错误的。因为这里涉及到了信号的处理行为,子线程产生的信号应该也算是此进程产生的信号,那信号对应的处理方式是什么呢?这里找到 kernel 相关头文件里有说明 signal.h

主线程退出,子线程会退出吗?子线程崩溃,主线程会退出吗?相关推荐

  1. 让程序在崩溃时体面的退出之总结

    终于把<让程序在崩溃时体面的退出>这个系列的6篇文章全部发表出来了.         这6篇文章分别是:         < 让程序在崩溃时体面的退出之Unhandled Excep ...

  2. python线程的注意点(线程之间执行是无序的、主线程会等待所有的子线程执行结束再结束(守护主线程)、线程之间共享全局变量、线程之间共享全局变量数据出现错误问题(线程等待(join)、互斥锁))

    1. 线程的注意点介绍 线程之间执行是无序的 主线程会等待所有的子线程执行结束再结束 线程之间共享全局变量 线程之间共享全局变量数据出现错误问题 2. 线程之间执行是无序的 import thread ...

  3. P576线程P582多线程P583startP584Runnable创建线程P58子线程应用P587退出P588方法P591守护线程P592线程7大状态P593同步P594互斥锁P596释放锁P598

    576线程-P598作业2 P576线程 P582多线程机制 public class Thread01 {public static void main(String[] args) {//创建Ca ...

  4. 主线程 唤醒_Java等待唤醒机制统计子线程运行时间的方式及其疑问

    我想在主线程中获取子线程运行的时间,一种方式是使用join()方法,经验证是可行的: 但是我想试试等待唤醒机制,思路是:子线程启动后主线程等待,子线程结束后唤醒主线程,但是不太清楚为什么会报错,从运行 ...

  5. Android ThreadUtil 线程公共类,判断是否在主线程/ 子线程执行 相关操作

    前言:通常,我们写的公共的模块给别人用,但是这个模块又必须在特定的线程中执行. 比如,一个加载网络图片的的方法,需要在子线程中执行. /** * 加载网络图片 */ private void load ...

  6. 多线程学习--案例-子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次

    子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序. package Demo4; public class ThreadTe ...

  7. Java多线程面试题:子线程循环10次,接着主线程循环100,接着又回到子线程循环10次, 接着再回到主线程又循环100,如此循环50次

    近在学习多线程,特贴在这里,并附上自己所作答案(参考与张孝祥老师的方法). 题目如下: 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次, 接着再回到主线程又循环100,如此循环50 ...

  8. 详解Python线程对象daemon属性对线程退出的影响

    进程.线程的概念以及多线程编程的基础知识请参考文末给出的方式在公众号历史文章中查找相关文章进行阅读.本文重点介绍线程对象daemon属性在线程退出时产生的作用和影响. 首先,我们来看一下官方文档对守护 ...

  9. MFC之AfxbeginThread 线程 创建、挂起、释放、结束、退出

    MFC之AfxbeginThread 线程 创建.挂起.释放.结束.退出 本文简单阐述了如何使用一个afxbeginthread创建一个线程(两种方法,使用默认设置,使用自主设置参数),以及一些如同, ...

  10. 线程的退出 java_(转)Java结束线程的三种方法

    背景:面试过程中问到结束线程的方法和线程池shutdown shutdownnow区别以及底层的实现,当时答的并不好. 线程属于一次性消耗品,在执行完run()方法之后线程便会正常结束了,线程结束后便 ...

最新文章

  1. 使用OData服务创建SAP C4C的Lead数据,必须指定Account字段
  2. mysql数据库导入导出文件sql文件
  3. 三、MyBatis 使用传统 Dao 开发方式
  4. 用贪婪算法解决背包问题_解决主要算法问题的贪婪策略
  5. 小知识—PRINCE2的七大原则之剪裁
  6. java中的static类_再议Java中的static关键字
  7. c语言中各个符号的意义及作用是什么,C语言特殊符号意义
  8. maven修改本地仓库地址配置文件
  9. 插件占坑,四大组件动态注册前奏(三) 系统BroadCast的注册发送流程
  10. 做软件项目经理需要具备的品质和素质
  11. 汽车故障诊断技术【4】
  12. IDEA ideaIU点击无反应
  13. Mac系统安装Photoshop CS6教程
  14. jQuery入口函数的写法
  15. 本周最新文献速递20211128
  16. Gossiping闲聊路由协议
  17. 软件开发团队必备管理工具
  18. OPN/SPN/PLMN的区别
  19. svn ignore忽略文件
  20. 整数规划学习笔记(一)

热门文章

  1. 有眼前的代码,更要有诗和远方
  2. python_celery redis的读取
  3. TVM入门:TVM编译Pytorch模型工作流程
  4. 自定义Mono,实现Unity Android平台代码更新
  5. 计算机网红叫啥,计算机 | 看头号“网红”如何玩转科研
  6. noi题库(noi.openjudge.cn) 1.7编程基础之字符串T31——T35
  7. 中医诊所一定要去尝试软文营销,效果简直不要太好
  8. iCheck插件的使用 单选框选中与数据提交
  9. PPTV聚力传媒之Mesos集群性能测试
  10. 微信小程序:Flask+Gunicorn+gevent后端搭建(基于华为云)与前端部署