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

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(使用前将#替换为@)

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

  • TCP/IP编程实现远程文件传输

    TCP IP编程实现远程文件传输 在TCP IP网络结构中 为了保证网络安全 网络人员往往需要在路由器上添加防火墙 禁止非法用户用ftp等安全危害较大的TCP IP协议访问主机 而有时系统维护人员需要用ftp将一些文件从中心机房主机传到前端
  • Cpp关键字破解(三)【volatile】篇

    关键字总结 volatile 文章目录 关键字总结 volatile 0 前言 1 概念 2 作用 3 使用场景 4 volatile成员函数 5 代码体验 0 前言 参考几位前辈博客 汇总整理了一下 C 中volatile关键字的使用详解
  • fcgi程序两种编写风格

    fcgi进程可以写成单线程的 也可以写成多线程的 单线程就是main函数中有一个死循环 一直等待接受请求 有请求过来时 就处理请求 并返回结果 没有并发性 多线程也分两种模式 一种是main函数起多个线程 每个线程都独立接受请求 另一种是m
  • Qt启动页多线程

    Qt启动页多线程 项目需要在Qt进入启动页之前加载一个大模型文件 同时要有一个页面用来提示用户加载状态 这里就需要用到多线程了 如果在单线程操作 要么需要等到文件加载完毕后才能显示等待页 要么干脆跳过了模型文件的加载 都是不符合需求的 我们
  • 如何在spring框架中解决多数据源的问题

    在我们的项目中遇到这样一个问题 我们的项目需要连接多个数据库 而且不同的客户在每次访问中根据需要会去访问不同的数据库 我们以往在 spring 和 hibernate 框架中总是配置一个数据源 因而 sessionFactory 的 dat
  • 《unix环境高级编程》--- 进程环境

    终止码 main中返回一个整型值与用该值调用exit是等价的 include
  • Future 和 Callable

    一 Runnable 缺陷 不能返回一个返回值 不能抛出 checked Execption 二 Callable接口 类似于Runnable 被其他线程执行的任务 实现call方法 有返回值 三 Future的作用 Callable和Fu
  • 强烈推荐Linux深入学习必读的几本书

    2012 10 01 21 00 40 成为一名精通 Linux程序设计的高级程序员一直是不少朋友孜孜以求的目标 根据中华英才网统计数据 北京地区 Linux 程序员月薪平均为 Windows程序员的 1 8 倍 Java 程序员的 2 6
  • read和write函数

    read ssize t read int fd void buf size t count fd 文件描述符 通过open获得 buf 需要读取的数据的存放位置 数组的地址 count 指定数组的大小 返回值 成功 gt 0 返回实际读取
  • java数据迁移程序

    环境 mysql 目标 亿级数据迁移 最终耗时 1 2小时 服务器更佳 建议在晚上或者没人访问的情况下操作 思路 1 不能一下将所有数据 导入到目标数据表 耗时太久 且占用资源 所有就用程序批量执行 每次执行一个范围段 比如第一个线程 1
  • java使用线程池批量插入mysql数据

    首先我们使用最原始的for循环插入数据 for int i 0 i lt 100000000 i service add new LongTest setStatus 1 setName NumberUtil getPwdRandom 5
  • sem_init函数用法

    sem init函数 sem init函数是Posix信号量操作中的函数 sem init 初始化一个定位在 sem 的匿名信号量 value 参数指定信号量的初始值 pshared 参数指明信号量是由进程内线程共享 还是由进程之间共享 如
  • 条件变量(condition variable)详解

    原理 假设我们需要解决这样一个问题 一个列表记录需要处理的任务 一个线程往此列表添加任务 一个线程processTask处理此列表中的任务 这个问题的一个关键点在于processTask怎么判断任务列表不为空 一般有两种方法 一 proce
  • C++-std::unique_lock介绍和简单使用

    unique lock std unique lock比std lock guard更灵活 这种灵活性主要体现在以下几点 lock guard在构造时或者构造前 std adopt lock 就已经获取互斥锁 并且在作用域内保持获取锁的状态
  • 【Java】网络编程——多线程下载文件

    前言 多线程下载文件 比单线程要快 当然 线程不是越多越好 这和获取的源文件还有和网速有关 原理 在请求服务器的某个文件时 我们能得到这个文件的大小长度信息 我们就可以下载此长度的某一个片段 来达到多线程下载的目的 每条线程分别下载他们自己
  • [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实现简易HTTP服务器

    说实话 之前完全没有想过 我还能写出服务器 感觉服务器这么高端的东西 能会用就不错了 还能写 不吐槽了 开始了 这次的作业是搭建一个服务器 要能接收请求 并给浏览器返回正确响应 项目的下载地址 项目目标 实现一个简易的多线程服务器 可以处理
  • gcc搜索动态链接库的路径优先级排序

    GCC运行时 Linux动态链接库的搜索路径按优先级排序为 1 编译目标代码时 Wl rpath 指定的动态库搜索路径 当指定多个动态库搜索路径时 路径之间用冒号 分隔 2 环境变量 LD LIBRARY PATH 指定的动态库搜索路径 3
  • iOS线程初探(四) GCD 和 NSOperation 小结

    参考资料 关于iOS多线程 看我就够了 GCD 在GCD中 有两个概念很重要 那就是任务和队列 任务 其实就是你需要做的事情 一个Block而已 任务有两种执行方式 同步执行和异步执行 同步执行 会阻塞当前线程 直至该任务执行完成后当前线程
  • Java线程(Thread)生命周期的6种状态

    当线程被创建并启动以后 它既不是一启动就进入了执行状态 也不是一直处于执行状态 在线程的生命周期中 可能处于不同的状态 java lang Thread State 列举出了这6种线程状态 线程状态 导致状态发生条件 New 新建 线程刚被

随机推荐

  • 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