观察主线程退出对子线程的影响

news2024/10/1 21:24:38

✨主进程以pthread_exit(0)方式退出——线程退出
✨子线程pthread_cancel方式杀死父线程
✨主线程以return,exit(0)方式退出——进程退出
 🔱return
  🔱return在主函数
  🔶return在子函数
 🔶exit(0)
  🔶exit(0)在主函数
  🔱exit(0)在其他函数
✨主进程先于子进程退出状态时间线
✨总结

在这里插入图片描述

主进程以pthread_exit(0)方式退出——线程退出

主进程显示僵尸状态,子进程正常运行

void* Routine(void* t)
{
    int cnt=10;    
    while(cnt--)
    {
        cout<<"thread_1 is running"<<endl;
        sleep(1);
    }
    pthread_exit(0);
}
//1.主线程pthread_exit(0)退出对子线程的影响
void test1()
{
    // 主线程return退出——子线程能不能正常执行
    pthread_t tid;
    pthread_create(&tid,nullptr,Routine,nullptr);
    int cnt=5;
    while(cnt--)
    {
        cout<<"main thread is running"<<endl;
        sleep(1);
    }
    pthread_exit(0);
    // exit(0);// exit(0)是进程终止
    return;// 函数终止,线程并没有终止

    // 主线程pthread_exit(0)退出,子线程正常执行
}
int main()
{
    test1();
    
    return 0;
}

在这里插入图片描述

子线程pthread_cancel方式杀死父线程

子线程可以pthread_cancel方式杀死父线程,但是线程不能自杀

void* Routine(void* t)
{
    pthread_t id = *(pthread_t*)t;
    int cnt=10;    
    while(cnt--)
    {
        cout<<"thread_1 is running"<<endl;
        if(cnt==7) pthread_cancel(id);// 子线程在第3s的时候杀死主线程
        sleep(1);
    }
    pthread_exit(0);
}
//1.主线程pthread_exit(0)退出对子线程的影响

void test1()
{
    // 主线程return退出——子线程能不能正常执行
    pthread_t id = pthread_self();
    pthread_t tid;

    pthread_create(&tid,nullptr,Routine,&id);
    int cnt=5;
    while(cnt--)
    {
        cout<<"main thread is running"<<endl;
        sleep(1);
    }
    // pthread_exit(0);
    // exit(0);// exit(0)是进程终止
    return;// 函数终止,线程并没有终止

    // 主线程pthread_exit(0)退出,子线程正常执行
}
int main()
{
    test1();
    
    return 0;
}

在这里插入图片描述

主线程以return,exit(0)方式退出——进程退出

进程退出会直接终结所有线程

return

return在主函数

主函数return是终止进程

void* Routine(void* t)
{
    int cnt=10;    
    while(cnt--)
    {
        cout<<"thread_1 is running"<<endl;
        sleep(1);
    }
    pthread_exit(0);
}
int main()
{
    // test1();
    // 主线程return退出对子线程的影响
    pthread_t tid;
    pthread_create(&tid,nullptr,Routine,nullptr);
    int cnt=5;
    while(cnt--)
    {
        cout<<"main thread is running"<<endl;
        sleep(1);
    }
    // 主线程return退出,相当于exit,直接杀死进程
    return 0;
}

在这里插入图片描述

return在子函数

子函数return只是终止函数,并不会终止进程

void* Routine(void* t)
{
    int cnt=10;    
    while(cnt--)
    {
        cout<<"thread_1 is running"<<endl;
        sleep(1);
    }
    pthread_exit(0);
}
//1.主线程pthread_exit(0)退出对子线程的影响
void test1()
{
    // 主线程return退出——子线程能不能正常执行
    pthread_t tid;
    pthread_create(&tid,nullptr,Routine,nullptr);
    int cnt=5;
    while(cnt--)
    {
        cout<<"main thread is running"<<endl;
        sleep(1);
    }
    // pthread_exit(0);
    // exit(0);// exit(0)是进程终止
    return;// 函数终止,线程并没有终止

    // 主线程pthread_exit(0)退出,子线程正常执行
}
int main()
{
    test1();
    // 主线程return退出对子线程的影响
    // pthread_t tid;
    // pthread_create(&tid,nullptr,Routine,nullptr);
    int cnt=5;
    while(cnt--)
    {
        cout<<"main thread is running"<<endl;
        sleep(1);
    }
    // 主线程return退出,相当于exit,直接杀死进程
    // exit(0);
    
    return 0;
}

在这里插入图片描述

exit(0)

exit不论在哪里都是终止进程

exit(0)在主函数
void* Routine(void* t)
{
    int cnt=10;    
    while(cnt--)
    {
        cout<<"thread_1 is running"<<endl;
        sleep(1);
    }
    pthread_exit(0);
}
int main()
{
    // test1();
    // 主线程return退出对子线程的影响
    pthread_t tid;
    pthread_create(&tid,nullptr,Routine,nullptr);
    int cnt=5;
    while(cnt--)
    {
        cout<<"main thread is running"<<endl;
        sleep(1);
    }
    // 主线程return退出,相当于exit,直接杀死进程
    exit(0);
    return 0;
}

在这里插入图片描述

exit(0)在其他函数
void* Routine(void* t)
{
    int cnt=10;    
    while(cnt--)
    {
        cout<<"thread_1 is running"<<endl;
        sleep(1);
    }
    pthread_exit(0);
}
//1.主线程pthread_exit(0)退出对子线程的影响
void test1()
{
    // 主线程return退出——子线程能不能正常执行
    pthread_t tid;
    pthread_create(&tid,nullptr,Routine,nullptr);
    int cnt=5;
    while(cnt--)
    {
        cout<<"main thread is running"<<endl;
        sleep(1);
    }
    // pthread_exit(0);
    exit(0);// exit(0)是进程终止
    // return;// 函数终止,线程并没有终止
}
int main()
{
    test1();
    return 0;
}

在这里插入图片描述

主进程先于子进程退出状态时间线

请添加图片描述
不需要担心僵尸资源不会释放的问题,最终交由OS会释放

总结

  1. 主进程先于子进程退出——主进程僵尸,子进程正常运行
  2. exit——进程退出
  3. main函数return——进程退出
  4. 其他函数退出——函数退出
  5. pthread_exit(0)——线程退出
  6. pthread_cancel(id)——线程退出,不能自己杀自己,可以子杀父

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1505513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构——堆的应用 Topk问题

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

谷歌开源的LLM大模型 Gemma 简介

相关链接&#xff1a; Hugging face模型下载地址&#xff1a;https://huggingface.co/google/gemma-7bGithub地址&#xff1a;https://github.com/google/gemma_pytorch论文地址&#xff1a;https://storage.googleapis.com/deepmind-media/gemma/gemma-report.pdf官方博客&…

多址接入技术 ---FDMA、TDMA、CDMA

1、多址接入技术 所谓多址技术就是把同一个无线信道按照时间、 频率等进行分割, 使不同的用户都能够在不同的分割段中使用这一信道, 而又不会明显地感觉到他人的存在, 就好像自己在专用这一信道一样。 占用不同的分割段就像是拥有了不同的地址, 使用同一信道的多个用户就…

Vue.js过滤器:让数据展示更灵活

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Unity的相机跟随和第三人称视角二

Unity的相机跟随和第三人称视角二 展示介绍第二种相机模式远离代码总结 展示 我录的视频上可能看不太出来&#xff0c;但是其实今天的这个方法比原来写的那个方法更简便并且死角更少一些。 这里我也做了两个人物偏移的视角&#xff0c;按Q是原来的两个相机模式切换&#xff0c…

问题 | 程序员求职宝典

程序员的金三银四求职宝典 随着春天的脚步渐近,对于许多程序员来说,一年中最繁忙、最重要的面试季节也随之而来。金三银四,即三月和四月,被广大程序员视为求职的黄金时期。在这两个月里,各大公司纷纷开放招聘,求职者们则通过一轮又一轮的面试,力争心仪的职位。而如何在…

从零学习Linux操作系统 第三十二部分 Ansible中的变量及加密

一、变量的基本设定及使用方式 变量命名&#xff08;与shell相同&#xff09;&#xff1a; 只能包含数字&#xff0c;下划线&#xff0c;字母 只能用下划线或字母开头 .变量级别&#xff1a; 全局从命令行或配置文件中设定的paly:在play和相关结构中设定的主机:由清单&…

NeRF模型NeRF模型

参考视频&#xff1a;https://www.youtube.com/watch?vHfJpQCBTqZs&ab_channelVision%26GraphicsSeminaratMIT NeRF模型的输入输出: 输入: (x, y, z): 一个三维空间坐标,代表场景中的一个位置点(θ, φ): 视线方向,θ表示与y轴的夹角,φ表示与x轴的夹角,用两个角度可以…

(C语言)strcpy与strcpy详解,与模拟实现

目录 1. strcpy strcpy模拟实现&#xff1a; 实现方法1&#xff1a; 实现方法2&#xff1a; 2. strcat strcat模拟实现&#xff1a; 1. strcpy 作用&#xff1a;完成字符串的复制。 头文件&#xff1a;<string.h> destination是字符串要复制到的地点&#xff0c;s…

图片在div完全显示

效果图&#xff1a; html代码&#xff1a; <div class"container" style" display: flex;width: 550px;height: 180px;"><div class"box" style" color: red; background-color:blue; width: 50%;"></div><div …

FreeRTOS操作系统学习——同步互斥与通信

同步&#xff08;Synchronization&#xff09; 同步是一种机制&#xff0c;用于确保多个任务能够按照特定的顺序协调执行或共享数据。当一个任务需要等待其他任务完成某个操作或满足某个条件时&#xff0c;同步机制可以帮助任务进行协调和等待。 在FreeRTOS中&#xff0c;常见…

【布局:1688,阿里海外的新筹码?】1688重新布局跨境海外市场:第一步开放1688API数据采集接口

2023年底&#xff0c;阿里巴巴“古早”业务1688突然成为“重头戏”&#xff0c;尤其宣布正式布局跨境业务的消息&#xff0c;一度引发电商圈讨论。1688重新布局跨境海外市场&#xff1a;第一步开放1688API数据采集接口 2023年11月中旬&#xff0c;阿里财报分析师电话会上&…

SpringBoot项目如何部署到服务器

文章目录 准备&#xff1a;方式一&#xff1a;Jar包方式&#xff08;推荐&#xff09;部署步骤&#xff1a; 方式二&#xff1a;War包方式部署步骤&#xff1a; 总结 准备&#xff1a; 云服务器&#xff08;阿里云、腾讯云等&#xff09;Linux系统以及运行所需的环境 方式一&a…

数据结构部分

来源地址 一 数据结构 1 堆和树之间的区别 区别就在于树是没有特定顺序的&#xff0c;你需要遍历整个树才能找到特定元素&#xff1b;而堆是有序的&#xff0c;你可以直接找到最大&#xff08;或最小&#xff09;的元素。 堆&#xff1a;假设你正在开发一个任务调度系统&…

Java二叉树 (2)

&#x1f435;本篇文章将对二叉树的一些基础操作进行梳理和讲解 一、操作简述 int size(Node root); // 获取树中节点的个数int getLeafNodeCount(Node root); // 获取叶子节点的个数int getKLevelNodeCount(Node root,int k); // 获取第K层节点的个数int getHeight(Node r…

day06-网路编程

#include <myhead.h>int do_add(sqlite3 *ppDb) {int numb;char name[20];int age;int salary;printf("请输入要插入的信息:");scanf("%d %s %d %d", &numb, name, &age, &salary);char sql[128] "";sprintf(sql, "INSE…

Python算法(顺序查找/二分查找)

一。顺序查找法&#xff1a; 用途&#xff1a;主要用于查找无序的列表的某个元素 时间复杂度为O(n) 拓展&#xff1a;函数index&#xff08;&#xff09;运用的是顺序查找 二。二分查找法&#xff1a; 前提&#xff1a;被查找的列表顺序一定要是顺序的 用途&#xff1a;对…

java数值运算a/0 ;0/b; 0/0;结果

3/0indinity 无穷大 0/40 0/0NaN 不定值

JVM 常用监控工具介绍和使用

一、JPS 进程查看工具 用于列出当前系统中所有正在运行的 Java 进程。它的主要作用是查看 Java 进程的 PID&#xff08;进程标识符&#xff09;和主类名。可以帮助开发人员快速了解系统中正在运行的 Java 进程&#xff0c;对于监控和调试 Java 应用程序非常有用。 用法&#…

官网:所谓高大上,无非是把核心突出到了极致。

2023-10-30 14:37贝格前端工场 企业官网建设&#xff0c;客户往往要求高大上&#xff0c;但是很多设计师对高大上的解读存在了偏差&#xff0c;以至于设计的网站客户不满意&#xff0c;其实抓住官网所要展现的核心点&#xff0c;把核心点展现到极致&#xff0c;就是高大上。 …