当前位置: 首页 > news >正文

线程属性设置全攻略

目录

一、线程属性的概念

二、线程属性的核心函数

1. 初始化与销毁线程属性对象

2. 常用属性设置函数

三、线程属性的设置示例

1. 设置线程为分离状态

2. 设置线程栈大小

3. 设置线程调度策略和优先级

四、线程属性的关键注意事项

1. 分离状态(Detached State)

2. 栈大小(Stack Size)

3. 调度策略与优先级

4. 继承调度属性(Inherit Scheduler)

五、常见问题与解决方案

1. 线程栈溢出

2. 线程无法创建(资源不足)

3. 调度策略设置失败

六、线程属性设置的性能优化

七、总结


一、线程属性的概念

线程属性是 线程创建时可配置的参数,用于定制线程的行为和资源分配。通过设置线程属性,可以控制线程的栈大小、分离状态、调度策略、优先级等,从而优化程序性能和资源使用。


二、线程属性的核心函数

1. 初始化与销毁线程属性对象

#include <pthread.h>int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);
  • 作用
    • pthread_attr_init:初始化线程属性对象(默认值为系统默认属性)。
    • pthread_attr_destroy:释放线程属性对象占用的资源。

2. 常用属性设置函数

函数作用
pthread_attr_setdetachstate设置线程的分离状态(PTHREAD_CREATE_JOINABLE 或 PTHREAD_CREATE_DETACHED)。
pthread_attr_getdetachstate获取线程的分离状态。
pthread_attr_setstacksize设置线程的栈大小。
pthread_attr_getstacksize获取线程的栈大小。
pthread_attr_setschedpolicy设置线程的调度策略(如 SCHED_FIFOSCHED_RRSCHED_OTHER)。
pthread_attr_getschedpolicy获取线程的调度策略。
pthread_attr_setschedparam设置线程的调度参数(如优先级)。
pthread_attr_getschedparam获取线程的调度参数。
pthread_attr_setinheritsched设置线程是否继承创建者的调度策略(PTHREAD_INHERIT_SCHED 或 PTHREAD_EXPLICIT_SCHED)。
pthread_attr_getinheritsched获取线程的调度继承模式。

三、线程属性的设置示例

1. 设置线程为分离状态

#include <stdio.h>
#include <pthread.h>void* thread_function(void* arg) {printf("Thread is running.\n");return NULL;
}int main() {pthread_t thread_id;pthread_attr_t attr;// 初始化属性对象pthread_attr_init(&attr);// 设置分离状态pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);// 创建线程int ret = pthread_create(&thread_id, &attr, thread_function, NULL);if (ret != 0) {perror("pthread_create failed");return 1;}// 分离线程无需调用 pthread_joinprintf("Main thread continues.\n");// 销毁属性对象pthread_attr_destroy(&attr);return 0;
}

2. 设置线程栈大小

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>#define STACK_SIZE (1024 * 1024) // 1MB 栈大小void* thread_function(void* arg) {char buffer[1024 * 1024]; // 模拟栈使用printf("Thread is running.\n");return NULL;
}int main() {pthread_t thread_id;pthread_attr_t attr;void* stack = malloc(STACK_SIZE);if (!stack) {perror("malloc failed");return 1;}// 初始化属性对象pthread_attr_init(&attr);// 设置栈地址和大小pthread_attr_setstack(&attr, stack, STACK_SIZE);// 创建线程int ret = pthread_create(&thread_id, &attr, thread_function, NULL);if (ret != 0) {perror("pthread_create failed");free(stack);return 1;}// 等待线程结束pthread_join(thread_id, NULL);// 释放资源free(stack);pthread_attr_destroy(&attr);return 0;
}

3. 设置线程调度策略和优先级

#include <stdio.h>
#include <pthread.h>
#include <sched.h>void* thread_function(void* arg) {struct sched_param param;int policy;pthread_getschedparam(pthread_self(), &policy, &param);printf("Thread priority: %d, Policy: %d\n", param.sched_priority, policy);return NULL;
}int main() {pthread_t thread_id;pthread_attr_t attr;struct sched_param param;// 初始化属性对象pthread_attr_init(&attr);// 设置调度策略为 SCHED_FIFO(实时优先级)pthread_attr_setschedpolicy(&attr, SCHED_FIFO);// 设置调度继承模式为显式指定pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);// 设置优先级(需根据系统支持范围调整)param.sched_priority = 50;pthread_attr_setschedparam(&attr, &param);// 创建线程int ret = pthread_create(&thread_id, &attr, thread_function, NULL);if (ret != 0) {perror("pthread_create failed");return 1;}// 等待线程结束pthread_join(thread_id, NULL);// 销毁属性对象pthread_attr_destroy(&attr);return 0;
}

四、线程属性的关键注意事项

1. 分离状态(Detached State)

  • PTHREAD_CREATE_JOINABLE(默认):
    • 需要调用 pthread_join 回收资源。
    • 适用于需要获取线程返回值的场景。
  • PTHREAD_CREATE_DETACHED
    • 线程结束后自动释放资源。
    • 适用于无需等待线程结果的场景。

2. 栈大小(Stack Size)

  • 默认栈大小:通常为几 MB(依赖系统配置)。
  • 最小栈大小PTHREAD_STACK_MIN(通常为 2KB)。
  • 设置建议
    • 栈过小可能导致栈溢出。
    • 栈过大可能浪费内存,尤其在创建大量线程时。

3. 调度策略与优先级

  • 调度策略
    • SCHED_OTHER:默认策略,由系统动态调度。
    • SCHED_FIFO:先进先出的实时调度策略。
    • SCHED_RR:轮转调度的实时策略。
  • 优先级
    • 仅对 SCHED_FIFO 和 SCHED_RR 有效。
    • 需要 root 权限才能设置高优先级线程。
    • 优先级范围:sched_get_priority_min() 到 sched_get_priority_max()

4. 继承调度属性(Inherit Scheduler)

  • PTHREAD_INHERIT_SCHED(默认):
    • 线程继承创建者的调度策略和优先级。
  • PTHREAD_EXPLICIT_SCHED
    • 显式指定调度策略和优先级。

五、常见问题与解决方案

1. 线程栈溢出

  • 原因:栈空间不足,局部变量或递归调用过深。
  • 解决方案
    • 增加栈大小(pthread_attr_setstacksize)。
    • 避免在栈上分配大数组,改用堆内存。

2. 线程无法创建(资源不足)

  • 原因:系统资源限制(如最大线程数或内存不足)。
  • 解决方案
    • 减少单个线程的栈大小。
    • 使用 ulimit 调整系统限制(如 ulimit -s)。
    • 使用线程池管理线程生命周期。

3. 调度策略设置失败

  • 原因
    • 未启用实时调度策略(需 root 权限)。
    • 优先级超出系统支持范围。
  • 解决方案
    • 使用 sched_get_priority_min() 和 sched_get_priority_max() 查询合法范围。
    • 以 root 权限运行程序。

六、线程属性设置的性能优化

属性优化建议
栈大小根据线程需求调整,避免过大浪费或过小溢出。
分离状态对于短期任务使用 PTHREAD_CREATE_DETACHED,避免资源泄漏。
调度策略实时任务使用 SCHED_FIFO 或 SCHED_RR,普通任务使用默认策略。
优先级高优先级线程应谨慎使用,避免抢占系统关键资源。
继承调度属性显式设置调度属性可提高可控性,但需确保一致性。

七、总结

  • 线程属性设置 是多线程编程中的关键部分,直接影响线程的行为和资源使用。
  • 常用属性 包括分离状态、栈大小、调度策略和优先级。
  • 注意事项
    • 确保栈大小合理,避免溢出或浪费。
    • 优先级设置需符合系统权限和实时性需求。
    • 分离状态的选择应根据是否需要等待线程结果。
  • 错误处理:始终检查线程属性设置和创建函数的返回值。
http://www.lryc.cn/news/585996.html

相关文章:

  • 14. 请谈一下浏览器的强缓存和协商缓存
  • 9.2 埃尔米特矩阵和酉矩阵
  • Pandas 模块之数据的读取
  • arcgis投影后数据显示问题记录
  • 非程序员如何用 AI 提升日常工作效率:以产品经理为例的落地实践指南
  • error while loading shared libraries
  • 小架构step系列12:单元测试
  • [爬虫实战] 多进程/多线程/协程-异步爬取豆瓣Top250
  • Pytest 跳过测试技巧:灵活控制哪些测试该跑、哪些该跳过
  • linux系统mysql性能优化
  • H2在springboot的单元测试中的应用
  • 多 Agent 强化学习实践指南(一):CTDE PPO 在合作捕食者-猎物游戏中的应用详解
  • 引入了模块但没有使用”,会不会被打包进去
  • 【C++小白逆袭】内存管理从崩溃到精通的秘籍
  • c++反射实现
  • 张量数值计算
  • 跨系统开发代码换行符如何解决
  • 每日一SQL 【销售分析 III】
  • 试用了10款翻译软件后,我只推荐这一款!完全免费还超好用
  • 大模型KV缓存量化误差补偿机制:提升推理效率的关键技术
  • Qt6中出现 OpenCV(4.10.0) Error: Assertion failed
  • 第10讲——一元函数积分学的几何应用
  • 创建 UIKit 项目教程
  • 在 Java 中,计算两个 Integer 类型表示的合格数量与总数量的合格率,并保留四位小数,推荐使用 BigDecimal 来确保精度
  • springboot+swagger2文档从swagger-bootstrap-ui更换为knife4j及文档接口参数不显示问题
  • 股票的k线
  • 从基础加热到智能生态跨越:艾芬达用创新重构行业价值边界!
  • 人工智能自动化编程:传统软件开发vs AI驱动开发对比分析
  • 【科研绘图系列】R语言绘制小提琴图
  • 【TGRS 2025】可变形交互注意力Deform-Interac-Att,即插即用,涨点神器!