【Linux系统编程】31.pthread_detach、线程属性

目录

pthread_detach

参数pthread

返回值

测试代码1

测试结果

pthread_attr_init

参数attr

返回值

pthread_attr_destroy

参数attr

返回值

pthread_attr_setdetachstate

参数attr

参数detachstate

返回值

测试代码2

测试结果

线程使用注意事项

pthread_detach

       实现线程分离。线程分离状态:指定该状态,线程主动与主控线程断开关系。线程结束后,其退出状态不由其他线程获取,而直接自己自动释放。网络、多线程服务器常用。

man 3 pthread_detach

参数pthread

待分离的线程ID。

返回值

成功:0

失败:错误号

测试代码1

分离一个线程,并回收。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>

void *HuiDiao_HanShu(void *arg)
{
    printf("这是子线程的回调函数,子线程的进程ID是%d,子线程ID是%lu。\n", getpid(), pthread_self());
    return (void *)0;
}

int main(int argc, char *argv[])
{
    int flag;
    pthread_t ZiXianCheng_ID; //子线程ID
    void *num = NULL;

    flag = pthread_create(&ZiXianCheng_ID, NULL, HuiDiao_HanShu, NULL); //创建子线程
    if (flag != 0)
    {
        printf("创建子线程错误:%s\n", strerror(flag));
        exit(1);
    }

    printf("这是主线程,进程ID是%d,线程ID是%lu。\n", getpid(), pthread_self());

    printf("开始分离子线程!\n");
    flag = pthread_detach(ZiXianCheng_ID);
    if (flag != 0)
    {
        printf("分离子线程错误:%s\n", strerror(flag));
        exit(1);
    }
    printf("分离子线程完成!\n");

    printf("这是主线程,先睡一会,再回收子线程!\n");
    sleep(1);
    printf("这是主线程,睡醒了!\n");

    printf("开始回收子线程!\n");
    flag = pthread_join(ZiXianCheng_ID, &num);
    if (flag != 0)
    {
        printf("回收子线程错误:%s\n", strerror(flag));
        exit(1);
    }
    printf("回收子线程完成!\n");
    printf("num=%d\n", (int)num);

    pthread_exit(NULL);

    return 0;
}

测试结果

分离后的子线程结束后,会自动清理PCB,无需回收。

pthread_attr_init

初始化线程属性。

man 3 pthread_attr_init

参数attr

传出参数的属性。

返回值

成功:0

失败:错误号

pthread_attr_destroy

销毁线程属性所占用的资源。

man 3 pthread_attr_destroy

参数attr

传出参数的属性。

返回值

成功:0

失败:错误号

pthread_attr_setdetachstate

设置线程属性。

man 3 pthread_attr_setdetachstate

参数attr

已初始化的线程属性。

参数detachstate

分离线程:PTHREAD_CREATE_DETACHED

非分离线程:PTHREAD _CREATE_JOINABLE

返回值

成功:0

失败:错误号

测试代码2

设置线程的属性为分离属性,再回收子进程。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>

void *HuiDiao_HanShu(void *arg)
{
    printf("这是子线程的回调函数,子线程的进程ID是%d,子线程ID是%lu。\n", getpid(), pthread_self());
    return (void *)0;
}

int main(int argc, char *argv[])
{
    int flag;
    pthread_t ZiXianCheng_ID;         //子线程ID
    pthread_attr_t XianCheng_ShuXing; //线程属性
    void *num = NULL;

    flag = pthread_attr_init(&XianCheng_ShuXing); //初始化线程属性
    if (flag != 0)
    {
        printf("线程属性初始化错误:%s\n", strerror(flag));
        exit(1);
    }

    flag = pthread_attr_setdetachstate(&XianCheng_ShuXing, PTHREAD_CREATE_DETACHED); //设置线程属性为分离属性
    if (flag != 0)
    {
        printf("设置线程属性错误:%s\n", strerror(flag));
        exit(1);
    }

    flag = pthread_create(&ZiXianCheng_ID, &XianCheng_ShuXing, HuiDiao_HanShu, NULL); //创建子线程,借助线程属性将子进程分离
    if (flag != 0)
    {
        printf("创建子线程错误:%s\n", strerror(flag));
        exit(1);
    }

    flag = pthread_attr_destroy(&XianCheng_ShuXing); //销毁线程属性
    if (flag != 0)
    {
        printf("线程属性销毁错误:%s\n", strerror(flag));
        exit(1);
    }

    printf("这是主线程,进程ID是%d,线程ID是%lu。\n", getpid(), pthread_self());

    printf("这是主线程,先睡一会,再回收子线程!\n");
    sleep(1);
    printf("这是主线程,睡醒了!\n");

    printf("开始回收子线程!\n");
    flag = pthread_join(ZiXianCheng_ID, &num);
    if (flag != 0)
    {
        printf("回收子线程错误:%s\n", strerror(flag));
        exit(1);
    }
    printf("回收子线程完成!\n");
    printf("num=%d\n", (int)num);

    pthread_exit(NULL);

    return 0;
}

测试结果

说明子线程已被成功分离,无需回收。

线程使用注意事项

  1. 主线程退出其他线程不退出,主线程应调用 pthread_exit。

  2. 避免僵尸线程,被join线程可能在join函数返回前就释放完自己的所有内存资源,所以不应当返回被回收线程栈中的值。

  3. malloc和mmap申请的内存可以被其他线程释放。

  4. 应避免在多线程模型中调用fork除非马上exec,子进程中只有调用fork的线程存在,其他线程在子进程中均 pthread_exit。

  5. 信号的复杂语义很难和多线程共存,应避免在多线程引入信号机制。

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

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

相关文章

SpringCloud:认识微服务

程序员老茶 &#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; P   S : 点赞是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#…

NSSCTF | [SWPUCTF 2021 新生赛]easy_sql

打开题目&#xff0c;提示输入一些东西&#xff0c;很显眼的可以看到网站标题为“参数是wllm” 首先单引号判断闭合方式 ?wllm1 报错了&#xff0c;可以判断为单引号闭合。 然后判断字节数&#xff08;注意‘--’后面的空格&#xff09; ?wllm1 order by 3-- 接着输入4就…

[Linux][网络][网络层][IP协议]详细讲解

目录 0.基本概念1.IP协议头格式2.IP分片与组装1.为什么要分片&#xff1f;2.分片后谁来组装&#xff1f;3.这个分片操作传输层知道吗&#xff1f;4.如何识别报文和报文的不同&#xff1f;5.接收端&#xff0c;如何得知报文是独立的还是一个分片&#xff1f;6.如何区别哪些分片是…

UDP和TCP协议比较,TOE技术

如今在某些方面TCP超越UDP的主要原因如下 在硬件层面的TOE(TCP Offload Engine)功能&#xff0c;将越来越多的TCP功能卸载到网卡上。它极大地提升了TCP的性能&#xff0c;使其在高吞吐量场景下的表现更为出色。近年TCP的拥塞控制算法实现了显著进步。这些新算法显著提高了TCP在…

macos安装mysql一直卡在安装成功那个页面选项的解决办法

问题描述&#xff1a; 我安装的是比较新的版本8.0.37&#xff0c;安装过程中一直卡在安装那个选项上&#xff0c;且页面提示安装成功了&#xff0c;但就是死活不往下面的配置选项那一步走。 解决办法&#xff1a; 1.首先清理掉之前的mysql sudo rm -rf /usr/local/mysql2.然…

软件技术主要学什么课程

软件技术专业主要学习的课程和内容有编程语言、数据结构与算法、数据库技术等&#xff0c;以下是上大学网( www.sdaxue.com)整理的软件技术主要学什么课程&#xff0c;供大家参考&#xff01; 编程语言&#xff1a;掌握一种或多种编程语言&#xff0c;如C#、Java、Python、C等&…

Python 2.x与Python 3.x:初学者该如何选择?

自从Python在1994年首次发布以来,已经经历了多个版本的更新和改进。Python 1.x虽然在发展史上具有重要意义,但早已过时,不再用于实际开发。2000年发布的Python 2.x和2008年发布的Python 3.x则成为了Python家族中最常用的两个版本,形成了一个重要的分界线。特别是Python 3.x…

GPU通用计算介绍

谈到 GPU &#xff08;Graphics Processing Unit&#xff0c;图形显示卡&#xff09;大多数人想到的是游戏、图形渲染等这些词汇&#xff0c;图形处理确实是 GPU 的一大应用场景。然而人们也早已关注到它在通用计算上的巨大潜力&#xff0c;并提出了 GPGPU (General-purpose co…

本地搭建hydra服务用go以验证oidc流程

目录 1、docker搭建hydra&#xff0c;环境配置&#xff1a; 2、搭建完成后服务调用&#xff1a; 2.1保证服务正常启动&#xff1a; 2.2 通过postman调用&#xff0c;获取client_id&#xff1a; 2.3 通过client_id&#xff0c;实现oauth2/auth调用 3. 通过go语言实现oidc验…

jsp 实验12 servlet

一、实验目的 掌握怎样在JSP中使用javabean 二、实验项目内容&#xff08;实验题目&#xff09; 编写代码&#xff0c;掌握servlet的用法。【参考课本 上机实验1 】 三、源代码以及执行结果截图&#xff1a; 源代碼&#xff1a; inputVertex.jsp&#xff1a; <% page lang…

免费思维13招之四:主副型思维

免费思维13招之四:主副型思维 本节,给你分享一下产品型思维的第二种子思维:主副型思维 什么是主副型思维呢?传统的主副型思维是指对企业的核心、利润最高的产品进行收费,一些附加品、延伸产品进行让利,赠送给客户。 但是这早已过时了,现在升级之后的产品型思维,就是将…

​​​​【收录 Hello 算法】4.4 内存与缓存

目录 4.4 内存与缓存 4.4.1 计算机存储设备 4.4.2 数据结构的内存效率 4.4.3 数据结构的缓存效率 4.4 内存与缓存 在本章的前两节中&#xff0c;我们探讨了数组和链表这两种基础且重要的数据结构&#xff0c;它们分别代表了“连续存储”和“分散存储”两种物理…

如何防止WordPress网站内容被抓取

最近在检查网站服务器的访问日志的时候&#xff0c;发现了大量来自同一个IP地址的的请求&#xff0c;用站长工具分析确认了我的网站内容确实是被他人的网站抓取了&#xff0c;我第一时间联系了对方网站的服务器提供商投诉了该网站&#xff0c;要求对方停止侵权行为&#xff0c;…

16【PS Aseprite 作图】图像从Aseprite传输到PS

【内容背景】Aseprite很适合做像素图&#xff0c;有一个“完美像素”的选项&#xff0c;就不用在PS里面慢慢修线&#xff0c;能够省事很多 【具体操作】 勾选完美像素 Aseprite里面的“完美像素”能够减少修线的步骤&#xff0c;在“作图”的时候一定要注意勾选 导出 选择…

【全开源】Java线上云酒馆单预约系统源码小程序源码

核心功能&#xff1a; 座位预约&#xff1a;用户可以通过该系统提前预约酒馆的座位&#xff0c;选择就餐时间和人数&#xff0c;以及特殊座位&#xff08;如包厢、卡座等&#xff09;&#xff0c;确保到店后有合适的座位。酒水点餐&#xff1a;用户可以在预约的同时&#xff0…

OSError: image file is truncated (36 bytes not processed)解决方案

错误原因&#xff1a; 图像文件被损坏 解决方案&#xff1a; 代码开头添加如下两行代码&#xff1a; from PIL import ImageFile ImageFile.LOAD_TRUNCATED_IMAGES True

ETL工具kettle(PDI)入门教程,Transform,Mysql->Mysql,Csv->Excel

什么是kettle&#xff0c;kettle的下载&#xff0c;安装和配置&#xff1a;ETL免费工具kettle(PDI)&#xff0c;安装和配置-CSDN博客 mysql安装配置&#xff1a;Linux Centos8 Mysql8.3.0安装_linux安装mysql8.3-CSDN博客 1 mysql -> mysql 1.1 mysql CREATE TABLE user_…

RS2227XN功能和参数介绍及PDF资料

RS2227XN是一款模拟开关/多路复用器 品牌: RUNIC(润石) 封装: MSOP-10 描述: USB2.0高速模拟开关 开关电路: 双刀双掷(DPDT) 通道数: 2 工作电压: 1.8V~5.5V 导通电阻(RonVCC): 10Ω 功能&#xff1a;模拟开关/多路复用器 USB2.0高速模拟开关 工作电压范围&#xff1a;1.8V ~ 5…

【AIGC】重塑未来的科技巨轮

AIGC&#xff1a;重塑未来的科技巨轮 一、AIGC&#xff1a;从历史走来&#xff0c;向未来进发二、AIGC的三项核心技术三、AIGC的应用与未来 在当今科技飞速发展的时代&#xff0c;AI&#xff08;人工智能&#xff09;已经成为了一个无法忽视的热词。而与其紧密相连的AIGC&#…

01-01-4

1、字符的大小写转换 对应的代码&#xff1a; D:\Book\数据类型与运算符\数据类型与运算符\5、字符的大小写转换 int main() {char c a;//现在是小写字母a&#xff0c;要变为大写字母A。虽然赋值是字符a&#xff0c;但是本质上是将该字符对应的ASCII值放到该变量中c c - 3…