linux下线程分离属性

linux下线程分离属性

  • 一、线程的属性---分离属性
  • 二、线程属性设置
    • 2.1 线程创建前设置分离属性
    • 2.2 线程创建后设置分离属性

一、线程的属性—分离属性

什么是分离属性?
首先分离属性是线程的一个属性,有了分离属性的线程,不需要别的线程去接合自己的(回收自己的资源)。
a.线程的分离属性有两种:分离态(detached)和非分离态(joinable)。

b.非分离态的线程只有在调用pthread_join之后才会完全释放自己所占用的资源,可以用pthread_detach函数将线程修改为分离态,分离态的线程在线程结束后由系统自动释放其所占用的所有资源;
c.线程创建后默认属性是非分离态,需要调用pthread_join释放线程所占用的资源;

但是虽然说是分离的,但是进程退出了,该线程还是会退出的。
总结:
设置了分离属性的线程 -> 不需要pthread_join()
设置了非分离属性的线程 -> 需要pthread_join() -> 默认创建的普通属性线程就是非分离线程。
退出进程,所有子线程都会消亡,系统会回收他们资源。

如果设置为非分离属性的线程,且不去回收子线程资源,那么一个进程创建的子线程数据是有限,请下面程序(环境ubuntu20.04 64位)

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

//定义退出的值为全局变量
int retval = 10;

//子线程
void *start_pthread(void *arg)
{
    int cnt = 0;

    printf("arg:%ld\n", *((unsigned long *)arg));

}


int main(void)
{
    int cnt = 0;

    unsigned long val = 0;

    pthread_t  thread_id;


    //主线程 运行时间比子线程时间长,主线程运行退出后,回收子线程资源
     while (1)
     {
        //线程创建 非分离
        int ret = pthread_create(&thread_id, NULL, start_pthread, &val);

        if(ret != 0)
        {
            printf("pthread_create fail\n");
            return -1;
        }    
        val++;

     }



    printf("接合子线程成功\n");
     
    return 0;

}

运行效果
在这里插入图片描述

如果不设置为分离属性(主不回收子线程资源),创建到32749条时,创建线程失败

二、线程属性设置

线程属性设置通常有两个种,一种是在创建前设置好分离属性,别一个种是线程运行后,再设置线程属性接下来先看第一种情况。

2.1 线程创建前设置分离属性

线程创建前设置分离属性就是添加一个分离属性到一个属性变量中,然后使用属性变量去创建一个线程,那么创建出来的线程就是具有分离属性的线程。
接下来看函数

1)定义一个属性变量 -> 数据类型:pthread_attr_t

pthread_attr_t attr;

2)初始化属性变量。 -> pthread_attr_init() -> man 3 pthread_attr_init

#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);

参数:
attr:未初始化的属性变量
返回值:
成功:0
失败:非0错误码
3)设置分离属性到属性变量中。

#include <pthread.h>
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

参数:
attr:已经初始化过的属性变量
detachstate:
PTHREAD_CREATE_DETACHED -> 分离属性
PTHREAD_CREATE_JOINABLE -> 非分离属性 等同于 pthread_create(&thread_id, NULL, start_pthread, &val);
返回值:
成功:0
失败:非0错误码
4)使用属性变量去创建一个新的线程。

pthread_create(&tid,&attr,.....);   -> 创建出来的线程就是分离属性的线程,不需要pthread_join()

5)销毁属性变量。 -> pthread_attr_destroy() -> man 3 pthread_attr_destroy

int pthread_attr_destroy(pthread_attr_t *attr);

参数:
attr:已经初始化过的属性变量
返回值:
成功:0
失败:非0错误码

案例代码

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

//定义退出的值为全局变量
int retval = 10;

//子线程有分离--不需要接合
void *start_pthread(void *arg)
{
    int cnt = 0;

    printf("arg:%ld\n", *((unsigned long *)arg));

}


int main(void)
{
    int cnt = 0;

    unsigned long val = 0;

    pthread_t  thread_id;
    //定义分享属性变量 
    pthread_attr_t attr;

    //初始化属性变量
    pthread_attr_init(&attr);

    //设置线程属性--分离属性
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    //主线程 运行时间比子线程时间长,主线程运行退出后,回收子线程资源
     while (1)
     {
        //线程创建 分离属性
        int ret = pthread_create(&thread_id, &attr, start_pthread, &val);

        if(ret != 0)
        {
            printf("pthread_create fail\n");
            return -1;
        }    
        val++;

     }



    printf("接合子线程成功\n");
     
    return 0;

}

在这里插入图片描述
分离属性后的线程,可以自动消亡,主线程可以无限创建子线程。

2.2 线程创建后设置分离属性

先创建一个普通线程(分享属性设置为NULL, 默认的分享属性为不分离),然后在线程中调用一个设置分离属性的函数,那么这个线程就变成分离的属性。
1)设置线程本身的属性为分离属性。 -> pthread_detach() -> man 3 pthread_detach

#include <pthread.h>
int pthread_detach(pthread_t thread);

函数作用:
设置分离属性给线程
参数:
thread:需要设置分离属性的线程的ID号
返回值:
成功:0
失败:非0错误码
2)获取线程的ID号。 -> pthread_self() -> man 3 pthread_self

#include <pthread.h>
pthread_t pthread_self(void);

参数:

返回值:线程的ID号。

案例

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



//子线程
void *start_pthread(void *arg)
{
    int cnt = 0;

    //获取线程ID
    pthread_t thread_id = pthread_self();

    //分离线程
    int ret = pthread_detach(thread_id);
    if(ret != 0)
    {
        printf(" pthread_detach fail\n");
        exit(0);
    }

     printf("arg:%ld\n", *((unsigned long *)arg));

}


int main(void)
{
    unsigned long val = 0;

    pthread_t  thread_id;


    //主线程 运行时间比子线程时间长,主线程运行退出后,回收子线程资源
     while (1)
     {
        //线程创建 默认为非分离
        int ret = pthread_create(&thread_id, NULL, start_pthread, &val);

        if(ret != 0)
        {
            printf("pthread_create fail\n");
            return -1;
        }    
        val++;
     }
     


    return 0;

}

在这里插入图片描述
设置了分离属性之后,子线程可以无限被创建。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

测试ALPHA开发板CAN1的设备树文件

一. 简介 前面一篇文章学习了 ALPHA开发板上的 CAN接口的设备节点信息&#xff0c;文章如下&#xff1a; ALPHA开发板修改CAN的设备树节点信息-CSDN博客 本文对设备树文件进行测试&#xff0c;即开发板加载 .dtb设备树文件。 二. 加载测试 CAN的设备树文件 1. 拷贝设备树…

认识String类

认识String类 前面我们学习了类和对象&#xff0c;这一小节咱们来谈String类 目录 认识String类前言一、String类的创建方式二、String引用类型的特点及方法1.存储内容2.String对象的比较3.字符串查找在这里插入图片描述4.转换&#xff08;一&#xff09;数字转为为字符串&…

Swift 结构化并发之全局 Actor 趣谈

概览 在 Swift 结构化并发构成的体系中,一个称为“演员”(Actor)的成员扮演了非常重要的角色,它被用来隔离和同步执行中的数据。 除了普通 Actor 以外,还有一个全局“演员”(Global Actor)的概念,它是做什么的?又有什么与众不同的长处呢? 在本篇博文中,您将学到如…

【Swagger】接口文档生成

文章目录 一、前后端分离开发流程二、YApi导入接口文档三、Swagger3.1 介绍3.2 使用步骤3.2.1 导入 knife4j 的maven依赖3.2.2 在配置类中加入 knife4j 相关配置3.2.3 配置类中设置静态资源映射3.2.4 访问测试 3.3 常用注解3.4 全局参数设置 四、YApi 与 Swagger 一、前后端分离…

网络安全实训Day8

写在前面 网络工程终于讲完了。这星期到了网络安全技术部分。 网络安全实训-网络安全技术 网络安全概述 信息安全&#xff1a;所有保障计算机硬件、系统、软件、数据不因有意或无意的行为导致的服务中断、数据损坏或丢失等安全事件的保障技术 网络安全&#xff1a;基于计算机…

Spark Stage

Spark Stage 什么是Stage Spark中的一个Stage只不过是物理执行计划其中的一个步骤&#xff0c;它是物理执行计划的一个执行单元。一个Job会被拆分为多组Task&#xff0c;每组任务被称为一个Stage&#xff0c;可以简单理解为MapReduce里面的Map Stage&#xff0c; Reduce Stag…

Oracle 使用OGG(Oracle GoldenGate) 实现19c PDB与MySQL5.7 数据同步

OGG 是一种基于日志的结构化数据复制软件&#xff0c;它通过解析源数据库在线日志或归档日志获得数据的增删改变化。 OracleMysqlIP address192.168.80.100192.168.80.16DB version19.2.05.7host nametempmysql OS version&#xff1a; CentOS 7.9 一&#xff0c;Oracle 服务…

文件上传二—WEB攻防-PHP应用文件上传中间件CVE解析第三方编辑器已知CMS漏洞

演示案例&#xff1a; PHP-中间件-上传相关-Apache&NginxPHP-编辑器-上传相关-第三方处理引用PHP-CMS源码-上传相关-已知识别到利用 #PHP-中间件-上传相关-Apache&Nginx 复现漏洞环境&#xff1a;vulhub &#xff08;部署搭建看打包视频&#xff09; 由于PHP搭建常用中…

深度学习(过拟合 欠拟合)

过拟合&#xff1a; 深度学习模型由于其复杂性&#xff0c;往往容易出现过拟合的问题。以下是一些深度学习中常见的过拟合原因和解决方法&#xff1a; 1. 数据量不足&#xff1a;深度学习模型通常需要大量的数据来进行训练&#xff0c;如果数据量不足&#xff0c;模型容易过度…

Python界面库Flet(1)介绍和快速使用

Python界面库Flet(1)快速上手使用 Author&#xff1a;Once Day Date&#xff1a;2024年3月19日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: Pyt…

Collection与数据结构 数据结构预备知识(二):包装类与泛型

1.包装类 在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类.可以把包装类理解为基本数据类型所对应的引用数据类型. 1.1基本数据类型与对应的包装类 基本数据类型包装类byteByteshortShortintIntegerlongLong…

基于springboot+vue的旅游网站

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

【wails】(10):研究go-llama.cpp项目,但是发现不支持最新的qwen大模型,可以运行llama-2-7b-chat

1&#xff0c;视频演示地址 2&#xff0c;项目地址go-llama.cpp 下载并进行编译&#xff1a; git clone --recurse-submodules https://github.com/go-skynet/go-llama.cpp cd go-llama.cpp make libbinding.a项目中还打了个补丁&#xff1a; 给 编译成功&#xff0c;虽然有…

C#新语法(持续更新)

文章目录 顶级语句全局using 指令Using资源管理文件范围的命名空间声明可空的引用类型记录(record)类型 顶级语句 C#9.0中直接在C#文件中直接编写入口方法的代码&#xff0c;不用类&#xff0c;不用Main。同一个项目中只能有一个文件具有顶级语句。顶级语句中可以直接使用await…

Mysql数据库深入理解

目录 一、什么是数据库 二、Mysql基本架构图 1.Mysql客户端/服务器架构 2.客户端与服务器的连接过程 3.服务器处理客户端请求 4.一条查询SQL执行顺序 4.1连接器 4.2查询缓存 4.3解析器 4.4执行器 4.4.1预处理阶段 4.4.2优化阶段 4.4.3执行阶段 5.一条记录如何存…

汇丰:当前的美股是泡沫吗?

汇丰认为&#xff0c;当前的风险资产并不构成泡沫&#xff0c;更类似于2017年的市场环境&#xff0c;风险资产有望继续稳步上升。 隔夜美股飙涨&#xff0c;标普创三个月最大周涨&#xff0c;纳指收盘创历史新高。结合去年以来的强劲表现&#xff0c;有观点认为由科技股支撑的…

网络安全笔记-day7,共享文件服务器

文件共享服务器 准备阶段 打开虚拟机win2003 创建文件 D:. —share   –down   |  test1.txt   |   —up     01xxx.txt     02xxx.txt 配置IP win2003 192.168.1.10 255.255.255.0 winxp 192.168.1.20 255.255.255.0 创建共享文件夹 创建共享&#xff1…

freeRTOS动态内存heap4源码分析

1 前言 随着功能安全的推广&#xff0c;动态内存分配在RTOS领域的用武之地将越来越小。但heap4毕竟是为RTOS量身打造&#xff0c;相对简单&#xff0c;作为堆内存管理的入门学习&#xff0c;仍是很不错的选择。 1.1 标准c库动态内存函数的弊端 对于标准C库的malloc和free函数&…

阿里云2核4G服务器优惠价格30元、165元和199元1年,轻量和ECS

阿里云2核4G服务器租用优惠价格&#xff0c;轻量2核4G服务器165元一年、u1服务器2核4G5M带宽199元一年、云服务器e实例30元3个月&#xff0c;活动链接 aliyunfuwuqi.com/go/aliyun 活动链接如下图&#xff1a; 阿里云2核4G服务器优惠价格 轻量应用服务器2核2G4M带宽、60GB高效…

安装mysql8.0.36遇到的问题没有developer default 选项问题

安装mysql8.0.36的话没有developer default选项&#xff0c;直接选择customer就好了&#xff0c;点击next之后通过点击左边Available Products里面的号和中间一列的右箭头添加要安装的产品&#xff0c;最后会剩下6个 安装完成后默认是启动了&#xff0c;并且在电脑注册表注册了…
最新文章