Linux CPU 亲和性(Affinity)的应用

发布时间 - 2026-01-23 00:00:00    点击率:
sched_setaffinity 设置进程或线程允许运行的 CPU 核集合,内核调度器仅在该掩码指定的核内调度,不强制固定单核;多核掩码下仍可能迁移,子进程继承但 exec 重置,默认不独占,需配合 IRQ 亲和性与 RT 限流调整。

什么是 sched_setaffinity,它到底在设什么

它设置的是进程(或线程)能运行在哪几个 CPU 核上,不是“绑定到某核”,而是“允许运行的核集合”。内核调度器会尊重这个掩码,在该集合内做调度,但不会强制轮转或固定到单个核——除非你只设了 1 位。

常见误解是认为设了亲和性就等于“独占”或“不迁移”,其实只要掩码里有多个 bit,进程仍可能在这些核之间迁移(比如负载均衡触发),只是不会跑到掩码外的核上去。

实操建议:

  • taskset -c 0,2,4-6 ./myapp 启动时指定,比运行后调 sched_setaffinity 更可靠(避免启动瞬间被调度到其他核)
  • 子进程默认继承父进程的亲和性掩码,但 fork 后 exec 会重置为系统默认(除非显式保留)
  • 检查当前值:读 /proc//status 中的 CPUS_allowed_list 字段,比 taskset -p 更准确(后者可能因线程数多而截断)

为什么 pthread_setaffinity_np 在多线程程序里容易失效

因为它是 per-thread 的,而很多线程库(如 glibc 的 pthread)在创建新线程时,会把亲和性重置为继承自创建者线程的值——但这个“继承”发生在 clone() 阶段,早于你调用 pthread_setaffinity_np 的时机。结果就是:你设了,但新线程一启动就又被覆盖。

更隐蔽的问题是,某些线程池(如 libuv、boost::asio)内部会主动调用 sched_setaffinity(0, ...) 清除掩码,以保证工作线程可跨核调度。

实操建议:

  • 在线程函数入口第一行立刻调用 pthread_setaffinity_np,不要依赖构造时设置
  • 若用 C++ std::thread,需在 lambda 或函数对象里手动设,不能靠 std::thread 构造参数传递
  • 验证是否生效:在目标线程里读 sched_getaffinity(0, sizeof(mask), &mask),别只信启动命令

硬中断(IRQ)亲和性和进程亲和性冲突怎么办

网卡收包中断默认可能落在 CPU 0 上,而你的高性能服务绑在 CPU 3–7;结果软中断(ksoftirqd)虽然能迁移到服务所在核,但硬中断处理仍卡在 CPU 0,造成缓存失效和锁竞争。这不是进程亲和性没设好,而是 IRQ 没对齐。

/proc/irq//smp_affinity_list 控制硬中断分发,它和进程亲和性是两套独立机制,互不感知。

实操建议:

  • 查网卡 IRQ 号:grep eth0 /proc/interrupts | awk '{print $1}' | tr -d ':'
  • 设 IRQ 到同组 CPU:echo "3-7" > /proc/irq//smp_affinity_list(注意:需 root,且部分内核版本要求写十六进制掩码)
  • 确认生效后,再观察 cat /proc/interrupts 对应列的计数是否只在目标核上增长
  • 如果用了 RPS/RFS,也要同步配 /sys/cla

    ss/net/eth0/queues/rx-0/rps_cpus
    ,否则软中断仍不均衡

实时任务(SCHED_FIFO)+ 亲和性组合下的陷阱

很多人以为“绑核 + 实时调度 = 稳定低延迟”,但漏掉关键一点:Linux 实时调度器默认启用 sysctl kernel.sched_rt_runtime_us 限流(默认 950ms/1s),一旦实时任务跑满,就会被强制 throttled,表现为周期性卡顿,且 top 不显示 CPU 占用率高——因为时间片被掐断了。

此时即使亲和性正确、无其他进程干扰,也会出现毫秒级抖动。

实操建议:

  • 先关限流:echo -1 > /proc/sys/kernel/sched_rt_runtime_us(生产环境慎用,需确保实时任务绝对可控)
  • 确认 ulimit -r 允许的最高优先级足够(默认常为 0,需 ulimit -r 99
  • chrt -f -p 99 设置策略和优先级,仅设亲和性不改调度类毫无意义
  • 真正压测时,用 perf sched latency 查看调度延迟直方图,别只盯平均值

最易被忽略的是:IRQ 亲和性、RT 限流、线程继承行为这三者叠加时,问题现象会相互掩盖。调试顺序错了,花半天也找不到根因。


# linux  # app  # c++  # 为什么  # echo  # print  # Lambda  # 继承  # class  # 线程  # 多线程  # Thread  # 对象  # tr  # 负载均衡  # 掩码  # 的是  # 多核  # 几个  # 就会  # 也会  # 多个  # 也要  # 找不到  # 很多人 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】  如何用AWS免费套餐快速搭建高效网站?  微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】  php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  简单实现Android验证码  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  Laravel如何配置Horizon来管理队列?(安装和使用)  魔方云NAT建站如何实现端口转发?  C语言设计一个闪闪的圣诞树  Laravel如何处理CORS跨域请求?(配置示例)  如何用搬瓦工VPS快速搭建个人网站?  🚀拖拽式CMS建站能否实现高效与个性化并存?  黑客入侵网站服务器的常见手法有哪些?  BootStrap整体框架之基础布局组件  如何撰写建站申请书?关键要点有哪些?  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践  Swift开发中switch语句值绑定模式  Laravel怎么使用Intervention Image库处理图片上传和缩放  Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  Android滚轮选择时间控件使用详解  如何在万网自助建站中设置域名及备案?  ,在苏州找工作,上哪个网站比较好?  如何在IIS服务器上快速部署高效网站?  详解vue.js组件化开发实践  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?  如何快速选择适合个人网站的云服务器配置?  免费网站制作appp,免费制作app哪个平台好?  网站制作企业,网站的banner和导航栏是指什么?  Laravel distinct去重查询_Laravel Eloquent去重方法  如何挑选优质建站一级代理提升网站排名?  Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康  Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧  高防服务器:AI智能防御DDoS攻击与数据安全保障  Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】  Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制  Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明  javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】  个人摄影网站制作流程,摄影爱好者都去什么网站?  黑客如何通过漏洞一步步攻陷网站服务器?  Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】  iOS正则表达式验证手机号、邮箱、身份证号等  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  电商网站制作价格怎么算,网上拍卖流程以及规则?  laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程  Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】  PHP正则匹配日期和时间(时间戳转换)的实例代码  如何在建站之星网店版论坛获取技术支持?