线程(2)/ 线程属性 /相关函数接口--- 嵌入式(Linux)

✨ 马年开工第一学,不负时光,不负成长!跟着博主一起深耕Linux线程编程,从基础到实战,吃透线程属性的核心用法,避开开发中的常见坑,加油冲起来~

在Linux线程编程中,线程属性是控制线程行为的关键,其中最常用、最核心的就是「分离状态(detachstate)」------ 它直接决定了线程结束后资源的回收方式。今天就带大家全面拆解线程属性,结合可直接运行的代码示例,帮大家真正学懂、会用。

1、线程的属性

线程的所有属性由 pthread_attr_t 结构体统一管理,我们无需手动定义该结构体的内部成员,只需通过对应的函数接口初始化、设置、销毁即可。

其中,分离状态(detachstate) 是最常用的线程属性,没有之一!它主要用于控制线程终止后,其占用资源(栈空间、线程控制块等)的回收机制。

💡 重点提示:线程默认的属性为「可加入状态(PTHREAD_CREATE_JOINABLE)」,这也是我们之前写基础线程代码时,必须调用 pthread_join() 回收线程的原因。

2、线程的两种分离状态

线程的分离状态分为「可加入(joinable)」和「分离(detached)」两种,二者的核心区别、特点及适用场景,用表格清晰对比(建议收藏):

状态类型 核心特点 适用场景
可加入(joinable) 1. 线程结束后不会自动回收资源,需手动调用 pthread_join() 回收; 2. 可通过 pthread_join() 获取线程退出状态; 3. 能实现主线程与子线程的同步; 4. 若不调用 pthread_join(),会产生 "僵尸线程"(占用系统资源)。 需要获取线程退出状态、需要线程同步的场景
分离(detached) 1. 线程结束后,系统自动回收其资源,无需调用 pthread_join();2. 无法通过 pthread_join() 获取线程退出状态(调用会直接失败); 3. 不存在僵尸线程问题; 4. 线程结束即回收,符合 "先结束先回收、后结束后回收" 的自然逻辑。 无需获取线程状态、无需同步的后台任务(如日志收集、定时检测)

3、线程属性相关函数接口

操作线程属性的核心函数有3个(初始化、设置、销毁),再补充1个动态设置分离状态的函数,所有函数均需包含头文件 #include <pthread.h>,且编译时必须链接 pthread 库(添加 -lpthread 参数)。

3.1 pthread_attr_init(初始化线程属性)

  • 函数原型:
cpp 复制代码
#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
  • 功能:初始化线程属性结构体(必须先初始化,才能设置属性);
  • 参数attr:指向未初始化的 pthread_attr_t 结构体的指针;
  • 返回值:成功返回 0,失败返回非 0 错误码;
  • 注意:未初始化的属性结构体直接使用会导致未定义行为。

3.2 pthread_attr_setdetachstate(设置线程分离状态)

  • 函数原型:
cpp 复制代码
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
  • 功能:设置线程的分离状态;
  • 参数
    • attr:已初始化的线程属性结构体指针;
    • detachstate:分离状态取值:
      • PTHREAD_CREATE_JOINABLE:可加入状态(默认);
      • PTHREAD_CREATE_DETACHED:分离状态;
  • 返回值:成功返回 0,失败返回非 0 错误码。

3.3 pthread_attr_destroy(销毁线程属性)

  • 函数原型:
cpp 复制代码
int pthread_attr_destroy(pthread_attr_t *attr);
  • 功能:销毁线程属性结构体,释放其占用的资源;
  • 参数attr:已初始化的线程属性结构体指针;
  • 返回值:成功返回 0,失败返回非 0 错误码;
  • 注意:结构体销毁后不可再使用,除非重新初始化。

3.4 动态设置分离状态(线程创建后)

如果线程创建时用了默认的 "可加入" 状态,也可以在线程内部调用 pthread_detach() 转为分离状态:

  • 函数原型:
cpp 复制代码
int pthread_detach(pthread_t thread);
  • 功能:将指定线程设置为分离状态;
  • 参数thread:目标线程的 ID(线程内可传 pthread_self() 表示自身);
cpp 复制代码
pthread_detach(pthread_self());
  • 返回值:成功返回 0,失败返回非 0 错误码。

示例 :创建 "分离状态" 的线程(通过属性设置)

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>

// 线程函数:分离线程的执行逻辑
void *detached_thread(void *arg) {
    printf("分离线程(ID:%lu)开始执行\n", (unsigned long)pthread_self());
    sleep(2); // 模拟任务执行
    printf("分离线程(ID:%lu)执行完毕,系统会自动回收资源\n", (unsigned long)pthread_self());
    // 无需返回状态,系统自动回收
    pthread_exit(NULL);
}

int main() {
    pthread_t tid;
    pthread_attr_t attr; // 线程属性结构体
    int err;

    // 1. 初始化线程属性
    err = pthread_attr_init(&attr);
    if (err != 0) {
        printf("初始化属性失败:%s\n", strerror(err));
        exit(1);
    }

    // 2. 设置线程为分离状态
    err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    if (err != 0) {
        printf("设置分离状态失败:%s\n", strerror(err));
        pthread_attr_destroy(&attr); // 失败时销毁属性
        exit(1);
    }

    // 3. 创建分离线程
    err = pthread_create(&tid, &attr, detached_thread, NULL);
    if (err != 0) {
        printf("创建分离线程失败:%s\n", strerror(err));
        pthread_attr_destroy(&attr);
        exit(1);
    }
    printf("主线程:创建分离线程(ID:%lu),无需调用pthread_join\n", (unsigned long)tid);

    // 4. 销毁线程属性(创建完成后即可销毁,不影响线程)
    pthread_attr_destroy(&attr);

    // 尝试调用pthread_join(会失败)
    err = pthread_join(tid, NULL);
    if (err != 0) {
        printf("pthread_join失败(分离线程无法join):%s\n", strerror(err));
    }

    // 主线程等待一段时间,确保分离线程执行完毕
    sleep(3);
    printf("主线程退出\n");
    return 0;
}

4、结尾碎碎念

马年开工第一学,搞定线程属性的核心用法,离Linux线程编程大神又近了一步~ 线程属性的分离状态是实战高频考点,建议大家多敲几遍示例代码,理解两种状态的区别和适用场景,避开僵尸线程的坑。

后续会持续更新线程编程的进阶内容(线程同步、互斥锁等),关注博主,一起深耕技术、共同成长!如果觉得这篇文章对你有帮助,欢迎点赞、收藏、评论,你的支持就是我更新的最大动力💪

#Linux线程 #线程属性 #pthread函数 #僵尸线程 #C语言实战 #马年开工学习

相关推荐
宵时待雨4 分钟前
linux笔记归纳3:linux开发工具
linux·运维·笔记
magrich19 分钟前
安装NoMachine并解决无外接显示器桌面黑屏
linux·运维·服务器
fish_xk34 分钟前
Linus基础指令
linux·服务器
宁波阿成1 小时前
在ubuntu22.04源码级安装sub2api
linux·运维·ubuntu·ai·api·token·中转站
charlie1145141911 小时前
嵌入式Linux驱动开发(7) 从虚拟设备到真实硬件 —— LED驱动硬件基础
linux·开发语言·驱动开发·内核·c
Mortalbreeze2 小时前
软件包管理器yum和编辑器vim详解 —— 附带vim配置链接
linux·服务器
李日灐2 小时前
< 7 > Linux 开发工具:git 版本控制器 和 cgdb/gdb 调试器
linux·运维·服务器·开发语言·git·调试器·gdb/cgdb
青木9602 小时前
前后端开发调试运行技巧
linux·服务器·前端·后端·npm·uv
c++之路2 小时前
C++ 模板
linux·开发语言·c++
云动课堂3 小时前
【运维实战】MySQL 8.0 数据库 · 一键自动化部署方案 (适配银河麒麟 V10 / 龙蜥 8 / Rocky Linux 8 / CentOS 8)
linux·运维·数据库