当前位置: 首页 > 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.dtcms.com/a/275901.html

相关文章:

  • 【C++11】右值引用详解
  • 同步、异步、阻塞、非阻塞之间联系与区别
  • 小皮面板搭建pikachu靶场并bp使用爆破模块破解
  • 传感器WSNs TheDataLinkLayer——X-MAC
  • vue3+vit+vue-router路由,侧边栏菜单,面包屑导航设置层级结构
  • Redis事件机制
  • 嵌入式领域编码合集(为什么中文会乱码)
  • Java开发八股文之基础篇
  • qt 正则表达式
  • [面试] 手写题-二分查找
  • linux学习第30天(线程同步和锁)
  • WordPress Ads Pro Plugin本地文件包含漏洞(CVE-2025-4380)
  • 计算机毕业设计springboot服装工厂移动报表软件设计 基于SpringBoot的服装企业移动端数据可视化系统 面向服装制造行业的移动报表与公告发布平台
  • 微服务环境下的灰度发布与金丝雀发布实战经验分享
  • 多路选择器的学习
  • 《Java Web程序设计》实验报告六 JSP+JDBC+MySQL实现登录注册
  • 【飞算JavaAI】一站式智能开发,驱动Java开发全流程革新
  • 20250712-1-Kubernetes 监控与日志管理-K8s日志管理与维护_笔记
  • Go语言中的Options模式
  • 【Go + Gin 实现「双 Token」管理员登录】
  • Linux驱动08 --- 数据库
  • MCU芯片的功能安全机制E2E的基本原理和应用实现
  • 解锁C++数据结构:开启高效编程之旅
  • IDEA+Eclipse+Lombok无效问题排查
  • Java 之字符串 --- String 类
  • 电脑上如何查看WiFi密码
  • 什么是Jaccard 相似度(Jaccard Similarity)
  • 蓝牙调试抓包工具--nRF Connect移动端 使用详细总结
  • 日志不再孤立!用 Jaeger + TraceId 实现链路级定位
  • 程序在计算机中如何运行?——写给编程初学者的指南