news 2026/6/10 18:49:26

Linux学习日记18:线程的分离

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux学习日记18:线程的分离

一、前言

前面我们学习了线程的一些基础知识,学习了线程的创建与使用,今天我们来学习线程的分离与同步。

二、线程分离

2.1、函数原型

函数原型如下:

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

参数:thread:设置为分离态的线程 ID(用户态 TID,由 pthread_create() 返回的 ID)。

返回值:成功:返回0;失败:返回对应的错误码。

2.2、工作原理

pthread_detach()本质是修改线程的分离状态属性,通知内核:该线程终止时,无需保留资源等待pthread_join(),自动回收资源;具体执行流程如下:

1、用户态方面:pthread库修改该线程对应的属性结构体(pthread_attr_t)中detachstate字段为PTHREAD_CREATE_DETACHED;

2、内核态层面: 库通过系统调用通知内核,标记该线程的 task_struct(任务结构体)为 “分离态”;

3、线程终止时:内核检测到分离态标记,会立即清理线程的栈、寄存器、TID 等资源,无需主线程干预。

注:分离操作不影响线程的执行,仅改变线程终止后的资源回收规则

2.3、典型示例

1、先创建再detach

先创建一个pthread_detach.c文件,然后输入以下代码:

#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <string.h> void *myfun(void *arg) { printf("child pthread id is %ld\n",pthread_self()); for(int i=0;i<5;i++) { printf("children i =%d\n",i); sleep(1); } return NULL;//子线程结束,自动回收资源并退出 } int main() { pthread_t pthid; int ret; ret = pthread_create(&pthid,NULL,myfun,NULL);//线程创建 pthread_detach(pthid);//线程分离 if(ret != 0) { printf("error number is %d\n",ret); printf("%s\n",strerror(ret)); } printf("parent pthread id is %ld\n",pthread_self()); for(int i=0;i<5;i++) { printf("parent i = %d\n",i); sleep(1); } sleep(2);//休眠2s,防止主线程快速退出导致进程退出 return 0; }

使用gcc编译器进行编译,运行结果如下:

可以看到,主线程并不会等待子进程,子进程在后台跑,子线程自动释放资源,这就是线程分离的目的。

2、创建时直接设置为分离态

有时不想手动设置分离态,可以让线程创建时直接分离,具体代码如下:

#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <string.h> void *myfun(void *arg) { printf("child pthread id is %ld\n",pthread_self()); for(int i=0;i<5;i++) { printf("children i =%d\n",i); sleep(1); } return 0; } int main() { pthread_t pthid; pthread_attr_t attr; //init pthread_attr_init(&attr);//初始化线程属性对象 //set pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);//设置线程为分离态 //set2 int ret; ret = pthread_create(&pthid,&attr,myfun,NULL);//创建线程,并使其天生就是分离状态 pthread_detach(pthid); if(ret != 0) { printf("error number is %d\n",ret); printf("%s\n",strerror(ret)); } printf("parent pthread id is %ld\n",pthread_self()); for(int i=0;i<5;i++) { printf("parent i = %d\n",i); sleep(1); } sleep(2); //kill attr pthread_attr_destory(&attr);//销毁属性对象(不影响已经创建的线程) return 0; }

使用gcc编译器进行编译,运行结果如下:

运行结果与第一种方法一样,但是这是创建时直接分离,避免了线程创建失败而导致后续分离操作无效的情况。

2.4、注意事项

1、分离状态不可逆:线程一旦通过 pthread_detach() 设为分离态,无法再改回joinable状态。如果后续试图调用 pthread_join(),会直接返回 EINVAL 错误。

2、调用时机越早越好,避免线程提前终止:若主线程创建子线程后,还没来得及调用 pthread_detach(),子线程就已经终止,此时调用 pthread_detach() 会返回 ESRCH(找不到线程);

3、不能对已终止的线程调用pthread_detach():线程终止后,其 TID 可能被内核复用(分配给新创建的线程),此时调用 pthread_detach() 可能误操作新线程,导致不可预期的问题。

4、分离线程崩溃仍会导致进程终止:pthread_detach() 仅改变资源回收方式,不改变线程与进程的资源共享关系:如果分离线程触发段错误、除零等异常,仍会发送信号终止整个进程。

5、主线程提前退出仍会杀死分离线程:分离线程只是 “终止后自动回收资源”,但如果主线程直接return/exit导致进程终止,所有分离线程仍会被强制杀死(需主线程 pthread_exit()或延时等待)。

6、不能同时调用 pthread_join() 和 pthread_detach():若先调用 pthread_join()阻塞等待线程,此时再调用 pthread_detach() 会返回 EINVAL;若先调用 pthread_detach() 分离线程,再调用 pthread_join()也会返回 EINVAL;

7、主线程无需分离(无意义):主线程的 TID 等于进程 PID,分离主线程不会改变 “主线程退出导致进程终止” 的规则,因此对主线程调用 pthread_detach()无实际意义,还可能返回 EINVAL 错误。

2.5、两种创建方法对比

二者对比如下:

特性pthread_detach()(动态分离)pthread_attr_setdetachstate()(静态创建)
调用时机线程创建后任意时间(需线程未终止)线程创建前(初始化属性时)
灵活性高(运行时决定是否分离)低(创建前确定,无法动态调整)
代码复杂度低(无需初始化属性结构体)高(需初始化 / 销毁属性结构体)
风险可能因线程提前终止导致调用失败无此风险(创建时直接设为分离态)
适用场景运行时才确定是否分离的场景提前确定无需等待的后台线程
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 17:21:22

【毕业设计】基于Spring Boot的会议预定管理系统的设计与实现基于springboot高校会议室预订管理系统(源码+文档+远程调试,全bao定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/10 18:26:09

SpellCraft加密工具架构解析与实战指南

项目速览 【免费下载链接】Abracadabra Abracadabra 魔曰&#xff0c;下一代文本加密工具 项目地址: https://gitcode.com/gh_mirrors/abra/Abracadabra SpellCraft是一款革命性的短文本加密工具&#xff0c;通过创新的多层加密架构&#xff0c;将普通内容转换为高度伪装…

作者头像 李华
网站建设 2026/6/9 18:11:17

京东金榜年度金奖出炉 京东JD FASHION爆款商品强势登榜

【大力财经】12月9日&#xff0c;2025京东金榜盛典于上海举行&#xff0c;正式揭晓2025年度获奖榜单。活动现场&#xff0c;京东JD FASHION多款产品斩获重磅奖项&#xff0c;伯希和冲锋衣裤、耐克跑步鞋、阿迪达斯运动休闲鞋、波司登男士羽绒服、海澜之家男士T恤、高梵女士羽绒…

作者头像 李华
网站建设 2026/6/10 13:52:16

终极指南:如何快速上手OpenAI一致性模型实现高效图像生成

终极指南&#xff1a;如何快速上手OpenAI一致性模型实现高效图像生成 【免费下载链接】diffusers-ct_imagenet64 项目地址: https://ai.gitcode.com/hf_mirrors/openai/diffusers-ct_imagenet64 一致性模型&#xff08;Consistency Models&#xff09;作为生成式AI领域…

作者头像 李华
网站建设 2026/6/10 17:19:51

39、C 源代码编译软件入门指南(上)

C 源代码编译软件入门指南(上) 1. 常见文件类型 在软件编译过程中,我们会遇到各种类型的文件,常见的有: - 源代码文件 :以 .c 、 .h 或 .cc 结尾。C 源代码文件可能出现在包目录的任何位置。C++ 源代码文件通常以 .cc 、 .C 或 .cxx 为后缀。 - 目标文…

作者头像 李华
网站建设 2026/6/10 17:07:06

MOSES分子生成基准测试平台:AI药物发现的终极解决方案

MOSES分子生成基准测试平台&#xff1a;AI药物发现的终极解决方案 【免费下载链接】moses 项目地址: https://gitcode.com/gh_mirrors/mo/moses 在药物研发的漫长旅程中&#xff0c;科学家们面临着一个巨大挑战&#xff1a;如何从数以亿计的潜在分子中快速筛选出有效候…

作者头像 李华