taskset 查询或设置进程绑定CPU(亲和性)

本文详细介绍了Linux taskset命令及其在绑核(CPU亲和性设置)上的应用,包括原因、用法、验证步骤,并展示了如何通过实例优化数据库密集型任务的性能。重点讨论了SMP架构和CPUaffinity的概念,以及如何通过nginx配置来实践线程绑定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

taskset命令用于设置进程(或 线程)的处理器亲和性(Processor Affinity),可以将进程(或 线程)绑定到特定的一个 或 多个CPU上去执行,而不允许将进程(或 线程)调度到其他的CPU上。

一、什么是绑核

所谓绑核,其实就是设定某个进程/线程与某个CPU核的亲和力(affinity)。设定以后,Linux调度器就会让这个进程/线程只在所绑定的核上面去运行。但并不是说该进程/线程就独占这个CPU的核,其他的进程/线程还是可以在这个核上面运行的。如果想要实现某个进程/线程独占某个核,就要使用cpuset命令去实现。

其实,很多情况下,为了提高性能,Linux调度器会自动实现尽量让某个进程/线程在同样的CPU上去运行。所以,除非必须,我们没有必要显式的去进行进程绑核操作。

如何绑核

taskset用于将某个进程/线程绑定到CPU的某个或某几个核上面,其用法如下:taskset -p pid

可以查出进程pid现在的绑核情况。

设置绑核有两种方法:掩码形式和列表形式

二、taskset 概述

我的 Linode十分繁忙,在跑一些密集操作数据库的Rake任务时尤其如此。但我观察发现,Linode服务器的4核CPU,只有第1个核心(CPU#0)非常忙,其他都处于idle状态。

不了解Linux是如何调度的,但目前显然有优化的余地。除了处理正常任务,CPU#0还需要处理每秒网卡中断。因此,若能将CPU#0分担的任务摊派到其他CPU核心上,可以预见,系统的处理能力将有更大的提升。

两个名词:

SMP (Symmetrical Multi-Processing):指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。

CPU affinity:中文唤作“CPU亲和力”,是指在CMP架构下,能够将一个或多个进程绑定到一个或多个处理器上运行。

2.1  安装taskset工具

yum install util-linux

调整进程优先权和利用taskset有效控制cpu资源

taskset 查询或设置进程(线程)绑定CPU(亲和性)
通过 taskset 命令可将某个进程与某个CPU核心绑定,使得其仅在与之绑定的CPU核心上运行。

线程是最小的内核执行调度单元,因此,准确地说是将某个线程与某个CPU核心绑定,而非某个进程。
taskset 是依据 线程PID(TID)查询或设置线程的CPU亲和性(与哪个CPU核心绑定)。

2.2  taskset 语法

taskset [options]   mask command [arg]...
taskset [options]   -p [mask] pid

2.2.1  常用参数

-a, --all-tasks 操作所有的任务线程
-p, --pid 操作已存在的pid
-c, --cpu-list 通过列表显示方式设置CPU(逗号相隔)
-V, --version           输出版本信息

2.3  taskset 的用法

由于当前主机仅有4个核心: 

默认情况下,PID=xxxx  的进程可以运行在任意的CPU核心上(0-3)    

2.3.1.  指定PID为8528的进程在CPU1上运行

taskset -pc 1 8528     查看进程(或 线程)允许允许CPU范围使用-c参数

pid 8528's current affinity list: 0-3
###Pid 8528的当前关联列表:0-3 

pid 8528's new affinity list: 1
  ####Pid 8528的新关联列

2.3.2.  更改具体某一进程(或 线程)CPU亲和性

taskset  -p   hexadecimal mask  PID/LWP

上面号线程可以在0~3号CPU之间允许,现在设置掩码0x11(二进制0001 0001),表示可以在0~3号CPU上允许。

2.3.3. 查看具体某一进程(或 线程)的处理器亲和性(掩码)

查询PID(TID)= 11266 的进程可用的CPU核心,掩码形式表示
Taskset -p 11266

查询 PID(TID)= 11266 的进程可用的CPU核心
Taskset -pc 11266

mask是16进制   f代表15  转为2进制就是1111

0x0F(十六进制) => 1111(二进制),最右起第一个1表示CPU核心#0,第二个1表示CPU核心#1…设置 PID(TID)= 10878 的线程可用的CPU核心到#0、#2上

只要taskset成功返回了,那就表示绑核一定成功了,即该进程已被绑到指定的核上面,而且taskset命令会显示原来的绑核(原来的可能是系统默认分配的核)情况,以及新的绑核情况。

2.3.4. 为具体某一进程(或 线程)CPU亲和性指定一组范围

taskset -cp 1,2  11266   使用-c参数

三、验证

 将nginx 绑定CPU

 安装nginx 服务

1、安装依赖包
yum -y install pcre-devel zlib-devel gcc gcc-c++ make

2、创建运行用户
useradd -M -s /sbin/nologin nginx

3、编译安装
cd /opt
tar zxvf nginx-1.12.0.tar.gz -C /opt/''.6hvcf

cd nginx-1.12.0/
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module

make && make install

4、优化路径
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/

5、添加 Nginx 系统服务
vim /lib/systemd/system/nginx.service
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target

chmod 754 /lib/systemd/system/nginx.service
systemctl start nginx.service
systemctl enable nginx.service
vim /usr/local/nginx/conf/nginx.conf

是因为nginx提供了更精确的控制。

conf/nginx.conf中,有如下一行:

worker_processes  1;

这是用来配置nginx启动几个工作进程的,默认为1。而nginx还支持一个名为worker_cpu_affinity的配置项,也就是说,nginx可以为每个工作进程绑定CPU。我做了如下配置: 

查询 nginx 的  pid

ps -C nginx -o pid

未重启nginx

 重启nginx

4个服务各自在不同的cpu上运行

修改回来服务在cpu上随机运行 

四、总结

taskset 查询或设置进程(线程)绑定CPU(亲和性)
通过 taskset 命令可将某个进程与某个CPU核心绑定,使得其仅在与之绑定的CPU核心上运行。

线程是最小的内核执行调度单元,因此,准确地说是将某个线程与某个CPU核心绑定,而非某个进程。
taskset 是依据 线程PID(TID)查询或设置线程的CPU亲和性(与哪个CPU核心绑定)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值