c++怎么设置线程优先级与cpu亲和性_c++ 多核处理器性能绑定【指南】
技术百科
穿越時空
发布时间:2026-01-01
浏览: 次 Linux下需用pthread_setschedparam设置线程优先级,仅std::thread对象无效;须root权限或CAP_SYS_NICE能力才能设SCHED_FIFO/RR实时策略,优先级范围1–99;绑定CPU用pthread_setaffinity_np,需检查CPU在线状态及错误码。
Linux 下用 pthread_setschedparam 设置线程优先级
在 Linux 中,C++ 线程(std::thread)底层通常基于 pthread,但标准库不暴露调度参数接口,必须用原生 pthread 函数操作。直接调用 pthread_sets 才能真正生效,仅改
chedparamstd::thread 对象本身无效。
注意:需要 root 权限或 CAP_SYS_NICE 能力才能提升实时优先级(如 SCHED_FIFO),否则会静默失败或返回 EPERM。
- 先用
pthread_self()获取当前线程 ID,再传给pthread_setschedparam - 策略选
SCHED_FIFO或SCHED_RR才支持优先级(SCHED_OTHER的priority必须为 0) - 优先级范围依赖策略:
SCHED_FIFO通常为 1–99,可通过sched_get_priority_min/max(SCHED_FIFO)查
struct sched_param param;
param.sched_priority = 50;
int result = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
if (result != 0) {
// 检查 errno,常见为 EPERM(权限不足)或 EINVAL(策略/优先级非法)
}
绑定线程到指定 CPU 核心用 pthread_setaffinity_np
pthread_setaffinity_np 是 GNU 扩展,非 POSIX 标准,但 Linux 上稳定可用。它控制线程只能在指定 CPU 核心上运行,避免跨核迁移开销,对低延迟场景关键。
容易踩的坑:CPU 编号从 0 开始,且需确认系统实际核心数(nproc 或 /sys/devices/system/cpu/online),绑到不存在的 CPU 会失败;另外,亲和性设置对子线程不继承,每个线程需单独设。
- 用
cpu_set_t类型构造掩码,CPU_ZERO清空,CPU_SET(2)表示启用 CPU 2 - 调用前确保目标 CPU 处于 online 状态(热插拔可能使某些 core offline)
- 若程序运行时被系统调度器抢占到其他核,说明亲和性未生效——大概率是没正确调用或返回值未检查
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(1, &cpuset); // 绑定到 CPU 1
int result = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (result != 0) {
// 检查 errno,常见为 EINVAL(CPU 编号越界)或 ESRCH(线程已退出)
}
std::thread 启动后如何安全获取并设置 pthread 层属性
std::thread 不提供公开的 native_handle() 类型定义,但标准允许其返回可转换为 pthread_t 的类型(GCC/Clang 下就是 pthread_t)。只要不依赖 ABI 细节,可直接转型使用。
关键点:必须在线程已启动、但尚未结束时调用,否则 native_handle() 可能为无效值;且不能在 join() 或 detach() 后使用。
- 用
auto handle = t.native_handle()获取句柄,再转为pthread_t - 优先级与亲和性设置建议放在新线程函数入口处,而非主线程中调用——避免竞态和时序问题
- 若线程函数是 lambda,捕获变量需注意生命周期,避免设置时线程已退出
实时调度 + CPU 绑定组合使用的典型陷阱
两者一起用时,性能收益明显,但错误配置反而导致卡死或吞吐暴跌。最常被忽略的是:实时线程若无主动让出(如 usleep、nanosleep、阻塞 I/O),会饿死其他进程,尤其当它跑满单核且优先级高于所有普通线程时。
- 不要把多个高优先级线程绑到同一 CPU 核——它们会互相抢占,失去实时性保障
- 避免在实时线程中调用可能分配内存、加锁或触发 page fault 的操作(如
std::cout、malloc) - 测试阶段务必用
taskset -c N ./a.out验证亲和性是否生效,再用chrt -f 50 ./a.out验证调度策略,比代码内调试更直观
真实场景里,优先级数字和 CPU 编号不是写死的常量,应从环境变量或配置文件读取,并做存在性校验——这点几乎所有人一开始都会忽略。
# 的是
# 放在
# 能在
# 要把
# 多个
# 不存在
# 绑定
# 能使
# 配置文件
# 再用
# auto
# linux
# 环境变量
# 对象
# c++
# 标准库
# 接口
# 线程
# gnu
# 继承
# Thread
# 处理器
# Lambda
# 句柄
# 主线程
# 常量
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- windows 10应用商店区域怎么改_windo
- C++如何使用Qt创建第一个GUI窗口?(入门教程
- 微信里的php文件怎么变mp4_微信接收php转m
- Win11怎么设置任务栏图标大小_Windows1
- Win10如何更改用户账户控制_Windows10
- Win11怎么关闭开机声音_Win11系统启动提示
- 如何在Golang中处理二进制数据_Golang
- Win10任务栏天气和资讯怎么关闭 Win10禁用
- Win11关机快捷键是什么_Win11快速关机方法
- Mac如何修复应用程序权限问题_Mac磁盘工具修复
- Mac如何开启夜览模式_Mac护眼模式设置与定时
- Win11怎么设置默认PDF阅读器 Win11修改
- Win11怎么关闭透明效果_Windows11个性
- mac怎么查看wifi密码_MAC查看已连接WiF
- MAC如何快速搜索大文件_MAC磁盘空间分析与冗余
- 如何在 Go 中可靠地测试含 time.Time
- Win10如何卸载预装Edge扩展_Win10卸载
- Win11怎么更改账户头像_Windows 11自
- 如何在Golang中使用replace替换模块_指
- php485支持哪些操作系统_php485跨系统支
- Win11怎么设置右键刷新选项_Windows11
- 如何使用Golang写入二进制文件_Golang
- Win10怎样设置闹钟贪睡时间 Win10闹钟贪睡
- c++中如何使用auto关键字_c++11类型推导
- php怎么捕获异常_trycatch结构处理运行时
- Win11怎么查看wifi信号强度_检测Windo
- php打包exe怎么传递参数_命令行参数接收方法【
- mac怎么右键_MAC鼠标右键设置与触控板手势技巧
- Win11怎么关闭自动维护 Win11禁用系统自动
- SAX解析器是什么,它与DOM在处理大型XML文件
- 如何使用Golang实现RPC序列化与反序列化_G
- Win11怎样安装网易云音乐_Win11安装网易云
- 如何在Golang中处理数据库事务错误_回滚和日志
- Python 模块的 __name__ 属性如何由
- c++中如何进行二进制文件读写_c++ read与
- php高频调试功能有哪些_php常用调试函数与工具
- Windows 11如何开启文件夹加密(EFS)_
- c++怎么用jemalloc c++替换默认内存分
- Win10如何更改开机密码_Windows10登录
- 使用类变量定义字符串常量时的类型安全最佳实践
- LINUX的SELinux是什么_详解LINUX强
- Win11怎么关闭粘滞键_彻底禁用Windows
- Win11怎么关闭定位服务_保护Win11位置隐私
- Windows 11如何查看系统激活密钥_Wind
- Win11局域网共享怎么设置 Win11文件夹网络
- Win11怎么设置麦克风权限_允许应用访问Win1
- Win11怎么开启远程桌面_Win11系统远程桌面
- php打包exe如何加密代码_防反编译保护方法【技
- 获取 PHP 文件最后修改时间的正确方法
- Win11鼠标灵敏度怎么调 Win11鼠标指针移动

QQ客服