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

C++编程实践——Linux下的CPU控制

一、Linux下资源的处理

与Windows操作系统相比,在Linux下,可能由于是开源的原因,对相关资源的控制更加细致全面。比如开发者都知道,其更新升级的源地址可以进行直接编辑应用;网络支持的文件句柄数量也可以编辑相关的配置文件进行处理。而对进程、内存等的监控和管理也可以在 /proc文件中的相关的配置文件中进行处理。比如下面的方法可以对交换内存进行设置:

echo 100 > /proc/sys/vm/swappiness

不过,大家还是要注意,在Linux下,各个方面的资源管理控制往往分为读和写以及对权限的需要。这个非常重要,往往这些细节被忽略导致一些意外的问题。举一个简单的例子,有些命令或文件如果不使用 root权限操作,则会显示没有这些命令或文件。这对于一些新手,可能会觉得是没有安装相关库,从而让操作者做一些额外的操作。

二、CPU的控制

而在实际的开发中,CPU的控制是一个相当重要的场景,毕竟从有计算机以来,几乎所有的工作和任务都是围绕着CPU进行的。特别是随着CPU的功能不断增强,从单核到多核,以及更高的工作频率,更大的缓存等等,这都产生了在不同粒度上对CPU资源进行管控的必要。要了解CPU的控制,就需要开发者熟悉操作系统相关的CPU的调度和控制原理,最好能与相对应的内核中的源码对应起来。来看一下调度器的主要数据结构:

struct sched_entity {//整体权重struct load_weight load;         struct rb_node run_node;         u64 exec_start;                 u64 sum_exec_runtime;// 虚拟运行时间u64 vruntime;                   u64 prev_sum_exec_runtime;     
};

当然,在不同的版本的内核中可能细节会有不同,大家可根据自己的实际版本来分析即可。
对CPU的控制,肯定是在内核源码控制更方便,但为了安全和方便,本文只介绍在应用层次上的CPU控制,这样会更适合广大开发者来学习和应用相关的技术。要想对CPU进行管理 ,首先需要可以查看相关的CPU信息的命令和工具,这样才能在些基础上进行CPU的管理,常见的CPU查看相关命令和工具有:

  1. 命令
#查看CPU的详细信息
lscpu
cat /proc/cpuinfo# 查看CPU频率
cpupower frequency-info
cat /proc/cpuinfo | grep "cpu MHz"
  1. 使用工具
    可以安装下面的工具:
# Ubuntu/Debian
sudo apt install cpufrequtils linux-tools-common

当然,相关的工具有很多,同时由于云技术的发展,更多的云相关的工具和软件也有很多,大家可以根据自己的情况来进行安装和应用

当知晓了当前的CPU应用情况又安装了相关管理工具后,就可以在当前实际项目中通过代码或命令等操作根据CPU的控制粒度进行细节上的管控,从而让其更友好的实现设计的目的。一般来说,对CPU的管控主要有以下几个方面:

  1. 设置频率
    这可以算是CPU应用的最基本、最粗暴的应用。特别是在某些可以超频应用的CPU上,更有效果
  2. 设置核心的应用
    即对多核心的CPU出于某种场景的应用,禁用或启用一些核心
  3. 设置CPU的亲和性和中断的亲和性
    这个在前面的DPDK等分析中介绍过,让某个CPU与某个进程或线程绑定,防止出现切换出现的效率问题
  4. 设置优先级
    这个相对来说要有些鸡肋,因为虽然在不同的操作系统上都有大量的优先级设置,但实际开放给上层应用的,却非常有限

在不同的场景下,对CPU的控制有很多种方式,这就需要开发者对实际的CPU的信息有着详细的掌握,这样才能根据其可控制的粒度和相关方法实现对CPU资源利用的最优化。知己知彼,百战百胜。

三、解决方案及示例

针对上面的应用,实现的方式主要有以下几种:

  1. 命令处理
    相关的操作命令如下:
# 查看信息
cpufreq-info
# 设置频率
sudo cpupower frequency-set -d 1.2GHz    # 最小频率
sudo cpupower frequency-set -u 3.5GHz    # 最大频率# 设置频率-需userspace
sudo cpupower frequency-set -f 2.4GHz# 禁用CPU核心服务
sudo systemctl stop cpuset# 查看进程的CPU亲和性
taskset -p <PID># 启动程序时绑定到特定CPU
taskset -c 0,1 ./app# 修改运行中进程的CPU亲和性
taskset -cp 0,2,4 <PID>
  1. 配置文件
    具体的配置文件如下控制:
# 查看CPU核心状态
cat /sys/devices/system/cpu/online
ls /sys/devices/system/cpu/cpu*/online
# 禁用CPU核心(禁用CPU1)
echo 0 | sudo tee /sys/devices/system/cpu/cpu1/online
# 启用CPU核心
echo 1 | sudo tee /sys/devices/system/cpu/cpu1/online# 创建CPU控制组
sudo mkdir /sys/fs/cgroup/testgroup# 设置CPU权重(默认100)
echo 300 > /sys/fs/cgroup/testgroup/cpu.weight# 设置CPU使用上限(单位:微秒)
echo "200000 200000" > /sys/fs/cgroup/testgroup/cpu.max# 添加进程到控制组
echo <PID> > /sys/fs/cgroup/testgroup/cgroup.procs# 编辑服务文件
sudo systemctl edit myservice# 添加以下内容:
[Service]
CPUWeight=300
CPUQuota=85%
CPUShares=1024# 编辑配置文件
sudo vim /etc/sysctl.d/99-cpu.conf# 设置参数
kernel.sched_min_granularity_ns = 12000000
kernel.sched_wakeup_granularity_ns = 16000000
kernel.sched_migration_cost_ns = 6000000# 使能配置
sudo sysctl -p /etc/sysctl.d/99-cpu.conf
  1. 代码控制
    cgroup有V1和V2版本的不同,一般来说推荐使用V2版本,特别是在云环境和虚拟环境下。判断系统使用哪个版本的方法可以使用下面的命令:
stat -fc %T /sys/fs/cgroup/
#输出 cgroup2fs,说明系统使用 cgroup v2;输出 tmpfs,说明使用 cgroup v1

注意:cgroup V2不兼容V1
下面看一下其具体的一个代码:

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include <sys/stat.h>
#include <unistd.h>void createCgroup(const std::string &cgroupPath) {if (mkdir(cgroupPath.c_str(), 0755) == -1) {exit(EXIT_FAILURE);}
}// 设置CPU限制:微秒,100000=100ms
void setCpuLimit(const std::string &cgroupPath, int cpuQuota) {std::string cpuMaxPath = cgroupPath + "/cpu.max";std::ofstream cpuMax(cpuMaxPath);if (!cpuMax.is_open()) {exit(EXIT_FAILURE);}cpuMax << cpuQuota << " 100000";cpuMax.close();
}// add cgroup
void addProcess(const std::string &cgroupPath, pid_t pid) {std::string procsPath = cgroupPath + "/cgroup.procs";std::ofstream procs(procsPath);if (!procs.is_open()) {exit(EXIT_FAILURE);}procs << pid;procs.close();
}int main() {//  rootif (getuid() != 0) {return EXIT_FAILURE;}const std::string cgroupName = "test_cgroup";const std::string cgroupPath = "/sys/fs/cgroup/" + cgroupName;createCgroup(cgroupPath);// limitsetCpuLimit(cgroupPath, 50000); // 50ms/100ms// add cgrouppid_t pid = getpid();addProcess(cgroupPath, pid);// testvolatile int i = 0;while (i < 1000000000) {i++;if (i % 10000000 == 0) {std::cout << "run task... " << i << std::endl;}}// rm cgrouprmdir(cgroupPath.c_str());return EXIT_SUCCESS;
}

代码非常简单,创建cgroup目录,添加当前进程到组并限制CPU资源,最后弄了一个测试的负载。

四、总结

开发者不但应该把代码掌握的深入,对应用环境,包括各种平台的实际情况也要相当清楚。这就和打仗一样,再好的军事技术如果无法与实践技术结合,结果可想而知。赵括其实就是一个活生生的例子。项目的实践是一个系统的工程,开发者切记不能只看到其中部分,而忽略全局。与大家共勉!

http://www.dtcms.com/a/528794.html

相关文章:

  • NTRU 公钥加密系统详解
  • 深入浅出 VGGNet:经典卷积神经网络解析
  • 盐城整站优化柳州做网站去哪家公司好
  • 协程:实战与系统集成(高级篇)
  • 芯片验证基石UVM:高效验证的方法论与挑战
  • 旅游网站开发的作用seo快排技术教程
  • 3DS-GBA-GBC-NDS-switch梦可宝精灵游戏合集 -全汉化游戏
  • VCS Verdi 2023安装
  • R语言~T检验
  • 春季大扫除:清理 Arch Linux 中的垃圾
  • 未在props中声明的属性
  • php网站iis设置同心食品厂网站建设项目任务分解
  • 中国启用WPS格式进行国际交流:政策分析与影响评估
  • 中文域名做的网站有哪些网站域名怎么做分录
  • Docker使用【镜像】
  • 全链路智能运维中的业务连续性保障与容灾切换机制
  • linux的文件系统
  • 英语四级真题完整版(1990-2025)|2025年6月最新试题+答案解析|可打印PDF
  • 网站开发 项目的人员分配建筑工程网络计划编制软件
  • React 06
  • 红河县网站建设昆明网站建设哪家
  • 社区互助养老系统设计与实现方案
  • 服装购物商城网站建设安徽六安旅游必去十大景点
  • 「用Python来学微积分」14. 连续函数的运算与初等函数的连续性
  • 红酒商城网站建设广告设计案例网站
  • Linux内核进程管理子系统有什么第六十七回 —— 进程主结构详解(63)
  • 哪个网站可以接针织衫做单淘宝上找人做网站
  • C++容器deque
  • 【NestJS】 OpenAPI文档:运行时动态生成揭秘
  • 关闭VSCode的GitHub Copilot功能