主线程退出后,子线程会不会退出

2023-11-19

        额,好吧,这是个标题党,其实所有的线程都是平级的,根本不存在主线程和子线程。下文所述为了方便,将在main函数中的线程看做主线程,其它线程看成子线程,特此说明。先考虑以下代码:

        

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

void* thrd_start_routine(void* v)
{
    sleep(10);
        printf("created thread\n");
}

int main()
{
        pthread_t thrdid;
                
        pthread_create(&thrdid, NULL, &thrd_start_routine, NULL);
        
        sleep(5);
        printf("main thread\n");        
        return  0;
}

运行,结果是5s休眠后,打印“main thread";程序退出

之前误认为线程和进程一样,主线程退出,子线程退出。再考虑以下代码;

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

void* thrd_start_routine(void* v)
{
    sleep(10);
        printf("created thread\n");
}

int main()
{
        pthread_t thrdid;
                
        pthread_create(&thrdid, NULL, &thrd_start_routine, NULL);
        
        sleep(5);
        printf("main thread\n");
        pthread_exit(NULL);  
        printf("main exit\n");      
        return  0;
}

结果输出 main thread ;5s后输出 created thread;注意u,此处的main exit并不输出

相较于上一个程序,只加了一句 pthread_exit(NULL);

原因:

之前一个程序是在打印主线程之后,程序return,间接调用了exit()函数,因为一个线程调用exit函数,导致整个进程的退出,系统回收所有的资源,当然所有 的线程都退出了。再第二个程序中;找到以下资料:

When you program with POSIX Threads API, there is one thing about pthread_exit() that you may ignore for mistake. In subroutines that complete normally, there is nothing special you have to do unless you want to pass a return code back using pthread_exit(). The completion won't affect the other threads which were created by the main thread of this subroutine. 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 that main() created before, you can dispense with calling any functions. But if you want to keep the process and all the other threads except 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 open after its termination.

在主线程退出时,要想系统并不回收进程的所有资源,可以调用pthread_exit();然后等其他线程终止退出。


然后考察一到面试题:

是否熟悉POSIX多线程编程技术?如熟悉,编写程序完成如下功能:

1)有一int型全局变量g_Flag初始值为0;

2) 在主线称中起动线程1,打印“this is thread1”,并将g_Flag设置为1

3) 在主线称中启动线程2,打印“this is thread2”,并将g_Flag设置为2

4) 线程序1需要在线程2退出后才能退出

5) 主线程在检测到g_Flag从1变为2,或者从2变为1的时候退出


我的代码如下:

#include <iostream>
#include <pthread.h>
#include <stdlib.h>
using namespace std;

int flag=0;

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

void* thread1(void *var);
void* thread2(void *var);

int main()
{
    pthread_t tid1,tid2;
    pthread_create(&tid1,NULL,thread1,&tid2);
    pthread_create(&tid2,NULL,thread2,NULL);
	pthread_cond_wait(&cond,&mutex);
	cout<<"init thread exit"<<endl;
	pthread_exit(NULL);
}

void* thread1(void *var)
{
//	pthread_detach(pthread_self());
	pthread_mutex_lock(&mutex);
	if(flag==2)
        pthread_cond_signal(&cond);
    cout<<"this is thread1"<<endl;
	flag=1;
	pthread_mutex_unlock(&mutex);
	pthread_join(*(pthread_t *)var,NULL);
    cout<<"thread1 exit"<<endl;
}

void* thread2(void *var)
{
//	pthread_detach(pthread_self());
	pthread_mutex_lock(&mutex);
	if(flag==1)
        pthread_cond_signal(&cond);
    cout<<"this is thread2"<<endl;
	flag=2;
	pthread_mutex_unlock(&mutex);
    cout<<"thread2 exit"<<endl;
}


如代码所示,如果此处在main函数中没有pthread_exit(),那在flag由1变2或者由2变1时,其它线程通知main函数中的线程,将使得主进程直接退出,其它另外的线程就终止了,可能等不到打印线程exit语句。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

主线程退出后,子线程会不会退出 的相关文章

  • 进程和线程的详解和区别

    1 进程和线程概述 我们都知道计算机的核心是CPU 它承担了所有的计算任务 而操作系统是计算机的管理者 它负责任务的调度 资源的分配和管理 统领整个计算机硬件 应用程序是具有某种功能的程序 程序是运行于操作系统之上的 2 进程 我们编写的代
  • 线程安全的单例模式

    线程安全的单例模式 单例模式 属于创建类型的一种常用的软件设计模式 通过单例模式创建的类在当前进程中只有一个实例 一份资源只能被申请加载一次 如何实现 饿汉模式 资源在程序初始化的时候就去加载 后边使用的时候直接使用 使用会非常流畅 但是有
  • JUC编程

    1 JUC JUC就是java util concurrent工具包的简称 这是一个处理线程的工具包 JDK 1 5开始出现的 1 传统的synchronized public class Synchronized public stati
  • 如何在spring框架中解决多数据源的问题

    在我们的项目中遇到这样一个问题 我们的项目需要连接多个数据库 而且不同的客户在每次访问中根据需要会去访问不同的数据库 我们以往在 spring 和 hibernate 框架中总是配置一个数据源 因而 sessionFactory 的 dat
  • volatile和synchronized的区别

    共性 volatile与synchronized都用于保证多线程中数据的安全 区别 1 volatile修饰的变量 jvm每次都从主存 主内存 中读取 而不会从寄存器 工作内存 中读取 而synchronized则是锁住当前变量 同一时刻只
  • 线程连接池

    第一种 Executors newCacheThreadPool 可缓存线程池 先查看池中有没有以前建立的线程 如果有 就直接使用 如果没有 就建一个新的线程加入池中 缓存型池子通常用于执行一些生存期很短的异步型任务 package tes
  • Java多线程并行处理任务的实现

    Java多线程并行处理任务的实现 在实际项目开发的过程中 遇到过需要处理一个由多个子任务组成的任务的问题 顺序处理起来会造成响应时间超长 用户体验不好的问题 我想到一个解决方案 即使用多线程并行处理子任务 思路就是使用ThreadPoolE
  • java使用线程池批量插入mysql数据

    首先我们使用最原始的for循环插入数据 for int i 0 i lt 100000000 i service add new LongTest setStatus 1 setName NumberUtil getPwdRandom 5
  • GDB多线程调试常用命令

    gdb调试命令 step和next的区别 当前line有函数调用的时候 next会直接执行到下一句 step会进入函数 查看内存 gdb p a 打印变量地址 gdb x 0xbffff543 查看内存单元内变量 0xbffff543 0x
  • sem_init函数用法

    sem init函数 sem init函数是Posix信号量操作中的函数 sem init 初始化一个定位在 sem 的匿名信号量 value 参数指定信号量的初始值 pshared 参数指明信号量是由进程内线程共享 还是由进程之间共享 如
  • Python爬虫——多线程爬虫如何实现?

    Python爬虫 多线程爬虫 1 多任务 2 主线程与子线程 2 1 何谓线程 主线程及子线程 2 2 查看线程数量 2 3 创建子线程 2 4 线程间的通信 3 线程间的资源竞争 4 互斥锁与死锁 4 1 互斥锁 4 2 死锁 4 3 避
  • 条件变量(condition variable)详解

    原理 假设我们需要解决这样一个问题 一个列表记录需要处理的任务 一个线程往此列表添加任务 一个线程processTask处理此列表中的任务 这个问题的一个关键点在于processTask怎么判断任务列表不为空 一般有两种方法 一 proce
  • [Java实现 Scoket实时接收Tcp消息 优化层层叠加]

    目录 前言 基础实现代码 描述 优化代码多线程处理客户端连接和消息接收 描述 再次优化异步实现 以下是使用 CompletableFuture 实现异步处理客户端请求的示例代码 描述 进一步优化的代码 Netty来实现Socket服务器 描
  • Java 多线程模式 —— Guarded Suspension 模式

    Part1Guarded Suspension 模式的介绍 我们只从字面上看 Guarded Suspension 是受保护暂停的意思 1Guarded Suspension 模式 在实际的并发编程中 Guarded Suspension
  • [QT编程系列-25]:多线程机制 - QThread和MoveToThread简介

    目录 第1章 简介 1 1 多线程的目的 1 2 QThread多线程使用方法 1 3 QT支持多线的步骤 第2章 QThread 2 1 概述 2 2 moveToThread 第1章 简介 1 1 多线程的目的 QThread类提供了一
  • JAVA使用线程池查询大批量数据

    前言 在开发过程中可能会碰到某些独特的业务 比如查询全部表数据 数据量过多会导致查询变得十分缓慢 虽然在大多数情况下并不需要查询所有的数据 而是通过分页或缓存的形式去减少或者避免这个问题 但是仍然存在需要这样的场景 比如需要导出所有的数据到
  • 线程池用例

    线程池逻辑类 public class TaskExecutorService private final ExecutorService pool private final ThreadPoolExecutor pool private
  • iOS线程初探(四) GCD 和 NSOperation 小结

    参考资料 关于iOS多线程 看我就够了 GCD 在GCD中 有两个概念很重要 那就是任务和队列 任务 其实就是你需要做的事情 一个Block而已 任务有两种执行方式 同步执行和异步执行 同步执行 会阻塞当前线程 直至该任务执行完成后当前线程
  • ScheduledThreadPoolExecutor周期定时任务异常处理踩坑的问题!!

    问题原因 在公司写项目的时候 有一个周期定时任务的需求 就想着阿里巴巴开发手册里不是说不能用Executors去创建线程池 因为存在如下问题 FixedThreadPool和SingleThreadPool 允许的请求队列长度为 Integ
  • 线程安全的集合类

    Java中提供了许多集合类 其中有的是线程安全的 有的是线程不安全的 线程安全的集合类有 1 Vector Vector类实现了一个 动态数组 与ArrayList相似 但Vector是同步访问的 2 Stack Stack是Vector的

随机推荐

  • 51单片机——舵机的原理及应用

    一 舵机介绍 舵机是一种位置伺服的驱动器 适用那些需要角度不断变换并能够保持的控制系统 如果我们想要完成遥控转头风扇这么一个项目 那么转头的工作由舵机来实现就最好不过了 二 舵机的工作原理 标准的舵机有三条引线 分别是电源线Vcc 地线GN
  • leetcode算法面试题:对称二叉树、对链表进行插入排序、多数元素

    对称二叉树问题 给定一个二叉树 检查它是否是镜像对称的 例如 二叉树 1 2 2 3 4 4 3 是对称的 1 2 2 3 4 4 3 但是下面这个 1 2 2 null 3 null 3 则不是镜像对称的 1 2 2 3 3 参考答案 c
  • 视频质量诊断&&视频质量分析

    一 随着平安城市 大安防的发展 监控摄像机数量的不断增加 给监控系统的维护工作带来了新的挑战 如何及时了解前端视频设备的运行情况 发现故障并检测恶意遮挡与破坏的不法行为已成为视频监控系统运行的首要迫切问题 对于成千上万个监控摄像机 依靠人工
  • MySQL根据某一个或者多个字段查找重复数据,并且保留某字段值最大的记录

    问题场景 当系统没有处理好并发操作的情况下 操作人员同时操作一张表的情况下 数据库有可能被插入相同记录 这些会带来隐藏的bug 解决思路一 解决并发操作的冲突 解决思路二 对数据库 MySQL 某张表去重 首先确定你的业务是否允许重复 不允
  • gojs 实用高级用法

    本文介绍的是在使用 gojs 制作图的过程中 你可能会碰到的问题的一些解决方案 gojs 是一个非常强大的可视化关系的js库 1 取消更新动画 问题 更新数据的时候 会触发渲染 有渲染动画 用户体验不好 方案 初始数据绘制 有动画 更新数据
  • disabled_button 攻防世界

    1 第一步还是看题目 重要知识点 按钮按不下去 前端知识 例如下面的代码
  • 【基础语法篇】Java必备基础(思维导图+代码)

    文章目录 基本语法 初识JDK 输入与输出 条件与循环 一维数组与二维数组 函数及其他补充 Java常用类 Number Math类 Arrays类 String类 关于 和equals 其他类 Object 异常处理 常见异常 异常的处理
  • 邻接表无向图--- C++

    邻接表无向图的介绍 邻接表无向图是指通过邻接表表示的无向图 上面的图G1包含了 A B C D E F G 共7个顶点 而且包含了 A C A D A F B C C D E G F G 共7条边 上图右边的矩阵是G1在内存中的邻接表示意图
  • CesiumJS 中文学习手册

    1 Getting Started 入门 2 Developer Guides 开发人员指南 Creating Entities 创建实体 Imagery 图层 Terrain 地形 3D Models 3D 模型 Camera
  • 短视频矩阵系统:批量剪辑+矩阵分发+线索收集产品开发搭建

    短视频矩阵系统是一种综合性的短视频营销链路 通过在不同平台上传布 推广和转载短视频内容 以达到品牌宣传的效果 通过不同平台的内容进行组合 剪辑 形成全方位 多渠道的短视频推广网络链路 一 短视频矩阵系统搭建常见问题 1 抖去推的短视频AI矩
  • go grpc环境安装

    1 安装protoc编译器 protoc可执行文件用于编译 protocolbuf proto文件 和 protobuf 运行时 它是 C 写的 其可以将proto文件翻译为指定语言的代码 比较简单的安装方式是直接下载编译好的二进制文件 仓
  • KNN算法优缺点、原理及参数最优解

    文章目录 1 KNN算法简介 1 1 简述 1 2 优缺点 1 3 适用数据范围 2 工作原理 2 1 训练样本集 2 2 电影类别的KNN分析 如何进行电影分类 在这里插入图片描述 2 3 欧几里得距离 Euclidean Distanc
  • java 反射、设计模式、枚举、注解

    类的对象 基于某个类 new 出来的对象 也称为实例对象 类对象 类加载的产物 封装了一个类的所有信息 类名 父类 接口 属性 方法 构造方法 通过反射获取类对象 通过类的对象 获取类对象 Student s new Student Cla
  • CSS层叠样式表-属性 /盒子模型

    1 属性 1 字体属性 官方文档 https www apiref com css zh properties font index htm 1 font style 指定字体风格 属性用法 描述 取值 normal italic obli
  • hbuilder 微信支付成功 需要通知服务器吗,整合Hbuilder,实现app的微信支付与支付宝支付...

    1 对于使用Hbuilder开发app对接的移动支付 相信关于这方面的文档有不少 本人今天简单说一下本身在作的时候碰见的坑 html 1 1 在app客户端 使用Hbuilder写客户端代码时候 必定要注意ios 这两个的顺序 要否则会出现
  • 计算机网络——数字数据的数字编码

    计算机网络 数字数据的数字编码 数字数据的数字编码就是如何把数字数据用物理信号的波形表示 即用高低电平表示二进制 1 不归零码 正电平代表1 负电平代表0 2 归零码 正脉冲代表1 负脉冲代表0 3 曼彻斯特编码 位周期中心的上跳代表0 周
  • 吴恩达与OpenAI官方合作的ChatGPT提示工程课程笔记

    吴恩达与OpenAI官方合作的ChatGPT提示工程课程笔记 下述代码均在煮皮特上运行喔 LLMs large language models Base LLM 基于文本训练数据来预测做 文字接龙 Instruction Tuned LLM
  • git小技巧:git blame && git show 查看某一行代码的修改历史

    先查看某行代码由谁写的 在哪个commit中提交的 git blame file name 其显示格式为 commit ID 代码提交作者 提交时间 代码位于文件中的行数 实际代码 类似于下面这样 f604879e yingyinl 201
  • 某某星图sign参数解密分析

    大家好 我是TheWeiJun 欢迎来到我的公众号 今天给大家带来星图sign参数的解密分析 希望大家能够喜欢 如果你觉得我的文章内容有价值 记得点赞 关注 特别声明 本公众号文章只作为学术研究 不用于其他用途 逆向与爬虫的故事 公众号 专
  • 主线程退出后,子线程会不会退出

    额 好吧 这是个标题党 其实所有的线程都是平级的 根本不存在主线程和子线程 下文所述为了方便 将在main函数中的线程看做主线程 其它线程看成子线程 特此说明 先考虑以下代码 include