CPU告警不用愁,用C语言编写CPU使用率限制程序

现在云服务已经深入千家万户了,不仅商用,私用也很多。很多云服务厂商也都有配套的服务器安全模块,可以检测网络流量异常、内存占用量和CPU占用率,并且允许人工设置告警阈值。例如,CPU持续大于90%10分钟,那么你可能就会收到一条告警通知。

有时,或许这样的告警是因为一些恶意行为或者bug导致。但是有时,我们希望我们编写的程序能够尽可能压榨性能去尽快处理一些工作,此时CPU占满或许是一个很正常的行为。可如此就会触发告警,加之一些同道告警强迫症发作,此时就会很为难。如果增加一些sleep操作,莫名其妙的睡眠似乎总是不够优雅与完美。
在这里插入图片描述那么,有没有什么好的解决方案呢?

今天码哥就给大家提供一种解决方案。
在这里插入图片描述
或许有些人听过用过docker,docker容器就是可以做到资源隔离与资源配额的。似乎是我们想要的,那么是否可以借鉴一下呢?

答案是肯定的。

很多时候,我们的程序只是一次性的任务,且有些任务还依赖一些框架,如果将这种任务装入docker容器运行,显然成本和收益的问题让我们内心不太通达。

在Linux中,这样的资源配额限制是通过cgroups来实现的,它能够限制CPU、内存、IO等资源的使用程度。当然cgroups还有一些其他的使用功能,这里就不额外延展啦。

为了应对上面的那种资源限制需求,码哥展示一个用C语言编写的启动程序,帮你轻松解决这类问题。
在这里插入图片描述
限于篇幅,我们只展示CPU限制的方式,内存和IO相关的限制方法与其类似,可参阅网上一些人的文章自行扩展。

下面直接上代码(受限于手机屏幕尺寸,建议大家PC端查看):

/*
 * Author: 码哥比特
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mount.h>
#include <sched.h>
#include <errno.h>
#include <string.h>
#include <dirent.h> 
#include <stdlib.h>
#include <sys/stat.h>

char *cpu = NULL;
char *group_name = NULL;
char cpu_basedir[256];
int deleted = 0;

static void print_help(char *name)
{
    printf("Usage:\n");
    printf("%s [OPTIONS] SHELL COMMAND\n", name);
    printf("\t-c\t\tset cpu rate\n");
    printf("\t-g\t\tgroup name\n");
    printf("\t-d\t\tdelete group\n");
}

static int parse_args(int argc, char *argv[])
{
    //...掠过一些参数解析部分
}

static void set_limit(void)
{
    int fd, n, pid = getpid();
    char tmp[1024];

    if (cpu != NULL) {
        if (mkdir(cpu_basedir, S_IRWXU) < 0) {
            if (errno != EEXIST) {
                fprintf(stderr, "create cpu group failed");
                exit(1);
            }
        }
        memset(tmp, 0, sizeof(tmp));
        snprintf(tmp, sizeof(tmp)-1, "%s/cpu.cfs_quota_us", cpu_basedir);
        if ((fd = open(tmp, O_WRONLY)) < 0) {
            fprintf(stderr, "open cpu file failed. %s\n", strerror(errno));
            exit(1);
        }
        memset(tmp, 0, sizeof(tmp));
        n = snprintf(tmp, sizeof(tmp)-1, "%s\n", cpu);
        write(fd, tmp, n);
        close(fd);

        memset(tmp, 0, sizeof(tmp));
        snprintf(tmp, sizeof(tmp)-1, "%s/tasks", cpu_basedir);
        if ((fd = open(tmp, O_WRONLY|O_APPEND)) < 0) {
            fprintf(stderr, "open cpu tasks failed. %s\n", strerror(errno));
            exit(1);
        }
        memset(tmp, 0, sizeof(tmp));
        n = snprintf(tmp, sizeof(tmp)-1, "%d\n", pid);
        write(fd, tmp, n);
        close(fd);
    }
}

int main(int argc, char *argv[])
{
    int idx = parse_args(argc, argv);
    if (group_name == NULL) {
        fprintf(stderr, "group name must be given\n");
        print_help(argv[0]);
        exit(1);
    }
    memset(cpu_basedir, 0, sizeof(cpu_basedir));
    snprintf(cpu_basedir, sizeof(cpu_basedir)-1, "/sys/fs/cgroup/cpu/%s", group_name);
    if (deleted) {
        remove(cpu_basedir);
    }
    if (idx) {
        set_limit();
        execv(argv[idx], argv+idx);
    }
    return 0;
}

为了节省篇幅,代码中略过了一些参数解析部分。从帮助信息中,我们也可大致看到程序的使用方式。

# ./cpuctl -c=89000 -g=test_group a.out  #姑且先叫cpuctl吧

这里,-g是用来设置资源组名的,避免和其他资源组冲突。-c是这个资源组下的所有进程CPU占用总和的上限数值,89000是89%的含义。这里要注意,如果你有两个进程在这个资源组下,那么两个进程是平分89%的,也就是每个进程44.5%。a.out则是我们要执行的程序。

我们用一个简单的死循环来测试一下:

#include <stdio.h>

int main(void)
{
    while (1) {}
    return 0;
}

正常情况下100%无疑,如图:
在这里插入图片描述
下面我们用我们的程序启动器来启动a.out并限制其CPU为89%,如图:
在这里插入图片描述
我们可以看到,其CPU占比会在89%上下小幅浮动,大家可自行尝试。

从代码中,我们可以看到,其实限制的方法是在/sys/fs/cgroup/cpu下建立一个test_group目录,然后向其内的cfs_quota_us文件写入限制额度,再向其内的tasks写入希望限制的进程ID。目前从码哥的使用情况来看,阿里和腾讯的cgroups配置都是在/sys/fs/cgroup中的,可能其他的操作系统有不同的路径。

喜欢的朋友可以关注码哥,也可以在评论区给码哥留言交流,谢谢观看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/318906.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

14、强化学习Soft Actor-Critic算法:推导、理解与实战

基于LunarLander登陆器的Soft Actor-Critic强化学习&#xff08;含PYTHON工程&#xff09; Soft Actor-Critic算法是截至目前的T0级别的算法了&#xff0c;当前正在学习&#xff0c;在此记录一下下。 其他算法&#xff1a; 07、基于LunarLander登陆器的DQN强化学习案例&#…

微信小程序(三)页面配置与全局配置

注释很详细&#xff0c;直接上代码 新增内容&#xff1a; 页面导航栏的属性配置全局页面注册配置全局导航栏配置样式版本 源码&#xff1a;(标准的json是不能加注释的&#xff0c;但为了方便理解咱做个违背标准的决定) 页面&#xff1a;index.json {//这里是页面的配置文件&am…

LAMA Inpaint:大型掩模修复

文章目录 一、大掩模修复&#xff08;LaMa&#xff09;简介二、大掩模修复&#xff08;LaMa&#xff09;的主要方法三、快速傅里叶卷积的修补网络四、损失函数五、训练中的动态掩膜生成 一、大掩模修复&#xff08;LaMa&#xff09;简介 LaMa方法的提出背景&#xff1a;现代图…

py连接sqlserver数据库报错问题处理。20009

报错 pymssql模块连接sqlserver出现如下错误&#xff1a; pymssql._pymssql.OperationalError) (20009, bDB-Lib error message 20009, severity 9:\nUnable to connect: Adaptive Server is unavailable or does not exist (passwordlocalhost)\n) 解决办法&#xff1a; 打…

【蓝桥杯日记】第一篇——系统环境的搭建

目录 前言 环境相关文件 学生机环境-Web应用开发环境&#xff08;第十五届大赛&#xff09; 学生机环境-Java编程环境&#xff08;第十五届大赛&#xff09; 学生机环境-C/C编程环境&#xff08;第十五届大赛&#xff09; 学生机环境-Python编程环境 &#xff08;第十五届…

【数据结构】八大排序之计数排序算法

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 一.计数排序简介及思想 二.计数排序代码实现 三.计数排序复杂度分析 &#x1f4cc;时间复杂度 &#x1f4cc;空间复杂度 结语 一.计数排序简介及思想 计数排序(Cou…

一个月带你手撕LLM理论与实践,并获得面试or学术指导!

大家好&#xff0c;我是zenRRan&#xff0c;是本号的小号主。 从该公众号的名字就能看出&#xff0c;运营已经好多年了&#xff0c;这些年当中直接或间接帮助很多同学从NLP入门到进阶&#xff0c;理论到实践&#xff0c;学校到企业&#xff0c;本科到硕士甚至博士。 每天习惯性…

【K12】Python写分类电阻问题的求解思路解析

分压电阻类电路问题python程序写法 一个灯泡的电阻是20Ω&#xff0c;正常工作的电压是8V&#xff0c;正常工作时通过它的电流是______A。现在把这个灯泡接到电压是9V的电源上&#xff0c;要使它正常工作&#xff0c;需要给它______联一个阻值为______的分压电阻。 解决思想 …

深度学习基本介绍-李沐

目录 AI分类&#xff1a;模型分类&#xff1a;广告案例&#xff1a; bilibili视频链接&#xff1a;https://www.bilibili.com/video/BV1J54y187f9/?p2&spm_id_frompageDriver&vd_sourcee6a6e7fec41c59c846c142eb5ef1da0b AI分类&#xff1a; 模型分类&#xff1a; 图…

初识 Elasticsearch 应用知识,一文读懂 Elasticsearch 知识文集(3)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

《现代C++语言核心特性解析》笔记草稿

仅供学习记录之用&#xff0c;谢绝转发 第1章 新基础类型&#xff08;C11&#xff5e;C20&#xff09; 1.1 整数类型long long 更多笔记 “在C中应该尽量少使用宏&#xff0c;用模板取而代之是明智的选择。C标准中对标准库头文件做了扩展&#xff0c;特化了long long和unsi…

【AIGC】Controlnet:基于扩散模型的文生图的可控性

前言 controlnet可以让stable diffusion的生图变得可控。 文章连接&#xff1a;https://arxiv.org/pdf/2302.05543.pdf 摘要 冻结了stable diffusion的预训练模型并重用它的预训练编码层神经网络结构与零初始化卷积层连接&#xff0c;从零开始逐渐增加参数&#xff0c;并确…

python入门,数据容器:set集合

set最大的特点就是不支持重复元素&#xff0c;可以进行元素的去重处理&#xff0c;但不有序&#xff0c;不保证元素顺序正确 所以就不能使用下标索引的访问 1.集合的定义 集合的定义使用的是大括号{ } 对ok这个字符串进行了去重 2.add添加新元素 3.remove移除元素 4.pop随机…

鸿蒙Harmony--AppStorage--应用全局的UI状态存储详解

无所求必满载而归&#xff0c;当你降低期待&#xff0c;降低欲望&#xff0c;往往会得到比较好的结果&#xff0c;把行动交给现在&#xff0c;用心甘情愿的态度&#xff0c;过随遇而安的生活&#xff0c;无论结果如何&#xff0c;都是一场惊喜的获得! 目录 一&#xff0c;定义 …

浅析Linux进程地址空间

前言 现代处理器基本都支持虚拟内存管理&#xff0c;在开启虚存管理时&#xff0c;程序只能访问到虚拟地址&#xff0c;处理器的内存管理单元&#xff08;MMU&#xff09;会自动完成虚拟地址到物理地址的转换。基于虚拟内存机制&#xff0c;操作系统可以为每个运行中的进程创建…

DHCP中继【新华三】

理论【DHCP服务器可以对其直连的网段中的pc&#xff0c;分配其IP地址等服务&#xff0c;但是&#xff0c;对于跨网段进行分配IP地址&#xff0c;需要中间有DHCP中继进行传达&#xff0c;由DHCP中继指定DHCP服务器的位置&#xff0c;可以很好的对其跨网段分配IP地址起到指引的作…

如何激活数据要素价值

文章目录 前言一、数据作为生产要素的背景二、数据作为新型生产要素&#xff0c;是价值创造的重要源泉&#xff08;一&#xff09;生产要素是经济活动中的基本要素&#xff08;二&#xff09;激活数据要素价值&#xff0c;要从理论上认识数据要素的基本特征&#xff08;三&…

爬虫—中信证券资管产品抓取

爬虫—中信证券资管产品抓取 中信证券资管产品板块网址&#xff1a;http://www.cs.ecitic.com/newsite/cpzx/jrcpxxgs/zgcp/ 页面截图如下&#xff1a; 目标&#xff1a;抓取上图中红框内的所有资产信息 按F12进入开发者工具模式&#xff0c;在Elements板块下&#xff0c;在…

大数据StarRocks(七):数据表创建

1. 基本概念 1.1 Row & Column 一张表包括行&#xff08;Row&#xff09;和列&#xff08;Column&#xff09;。Row 即用户的一行数据。Column 用于描述一行数据中不同的字段。 ⚫ 在默认的数据模型中&#xff0c;Column 只分为排序列和非排序列。存储引擎会按照排序列对…

Flask 小程序菜品搜索

mina/pages/food/index.wxml <!--index.wxml--> <!--1px 750/320 2.34rpx;--> <view class"container"><!--轮播图--><view class"swiper-container"><swiper class"swiper_box" autoplay"{{autoplay}…
最新文章