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

普洱建设网站wordpress 购买会员

普洱建设网站,wordpress 购买会员,金华网站建设电话,网站在哪里设置关键字一、背景 cgroup在如今的系统里基本都是默认打开的一个功能。对于cgroup的cpu子系统,默认的颗粒度是进程为维度进行cgroup的cpu及cpuset的控制。而对于一些复杂进程,可能的需求是进程里一些个别线程要绑定在X1-Xn这些cpu核上,而除了这些个别…

一、背景

cgroup在如今的系统里基本都是默认打开的一个功能。对于cgroup的cpu子系统,默认的颗粒度是进程为维度进行cgroup的cpu及cpuset的控制。而对于一些复杂进程,可能的需求是进程里一些个别线程要绑定在X1-Xn这些cpu核上,而除了这些个别线程之外的其他线程都需要绑定在Y1-Yn这些cpu核上。对于进程颗粒度的需求,一般来说systemd的能力就覆盖到了,但是对于这种相对复杂的线程颗粒度的需求,我们其实可以有几种处理方法。比如:

1)通过cpulimit进行CPU限制

——这种方式不需要root权限,原理是通过周期性地暂停和恢复进程(发送SIGSTOP和SIGCONT信号)来间接限制CPU限制,这种方式相对不太正式,属于“调试性”的限制方案。

2)通过管理服务或线程自己调用api进行线程级别的绑核控制

——在进程完全启动之后,通过绑核的api(sched_setaffinity)进行绑核设置,这种方式管理方式只能控制绑核,控不了cpu限额。我们倒是可以用systemd的进程限额能力配合这个管理服务的线程绑核能力来缝合成一个需求覆盖得相对全的功能。

3)通过cgroup的threaded功能进行分层的管理

——cgroup的threaded功能可以支持线程颗粒度的绑核和限额的控制,但是需要遵循一定的cgroup组层次结构的要求。另外这一个threaded功能目前还没有融进systemd里,这个控制需要另外的服务来做,当然另外的服务需要考虑当前系统里的要管控的进程的systemd的配置,这是需要一定的细节的。

这篇博客展开的是第三种方法,这种方法由于借助的是cgroup的能力,所以它对线程颗粒度的控制更加强大,为什么这么说,因为cgroup的设置一旦生效后,后续的非法的sched_setaffinity的设置都会被忽略,因为cgroup是一个强制的内核级别的管控功能,其他方式都需要遵照这样的规则。

下面第二章里,我们贴出测试程序源码,并进行成果展示,在第三章里,我们展开相关功能的一些细节。

二、测试源码及成果展示

2.1 测试源码

#include <iostream>
#include <thread>
#include <chrono>
#include <vector>
#include <string>
#include <cstdlib>
#include <fstream>
#include <unistd.h>
#include <sys/syscall.h>const int THREAD_COUNT = 200;
const int RUN_TIME_US = 100; // 100 us
const std::string CGROUP_NAME = "test/my_cgroup";// 获取线程的 TID
pid_t gettid() {return static_cast<pid_t>(syscall(SYS_gettid));
}void threadFunction(const std::string& cgroup_path) {// 将当前线程的 TID 写入 cgroup.threadsstd::ofstream cgroup_threads(cgroup_path + "/cgroup.threads", std::ios::app);if (cgroup_threads.is_open()) {cgroup_threads << gettid() << std::endl; // 写入当前线程的 TIDcgroup_threads.close();}while (true) { // 无限循环,您可以根据需要添加退出条件// 获取当前时间auto start_time = std::chrono::high_resolution_clock::now();// 进行 100 微秒的死循环auto end_time = start_time + std::chrono::microseconds(RUN_TIME_US);while (std::chrono::high_resolution_clock::now() < end_time) {// 当前循环只是占用CPU}// 计算剩余的时间并休眠auto sleep_duration = std::chrono::milliseconds(100) - (std::chrono::high_resolution_clock::now() - start_time);if (sleep_duration > std::chrono::milliseconds(0)) {std::this_thread::sleep_for(sleep_duration); // 休眠剩余时间}}
}void threadFunctionEx(const std::string& cgroup_path) {// 将当前线程的 TID 写入 cgroup.threadsstd::ofstream cgroup_threads(cgroup_path + "/cgroup.threads", std::ios::app);if (cgroup_threads.is_open()) {cgroup_threads << gettid() << std::endl; // 写入当前线程的 TIDcgroup_threads.close();}std::this_thread::sleep_for(std::chrono::seconds(1));std::string command = "/usr/bin/deadloop &";system(command.c_str());while (true) { // 无限循环,您可以根据需要添加退出条件// 获取当前时间auto start_time = std::chrono::high_resolution_clock::now();// 进行 100 微秒的死循环auto end_time = start_time + std::chrono::microseconds(RUN_TIME_US);while (std::chrono::high_resolution_clock::now() < end_time) {// 当前循环只是占用CPU}// 计算剩余的时间并休眠auto sleep_duration = std::chrono::milliseconds(100) - (std::chrono::high_resolution_clock::now() - start_time);if (sleep_duration > std::chrono::milliseconds(0)) {std::this_thread::sleep_for(sleep_duration); // 休眠剩余时间}}
}void createCgroup(std::string& cgroup_path) {// 创建 cgroup 目录cgroup_path = "/sys/fs/cgroup/" + CGROUP_NAME;std::string command = "mkdir -p " + cgroup_path;system(command.c_str());// 设置 cgroup 为线程模式std::ofstream cgroup_mode(cgroup_path + "/cgroup.type");if (cgroup_mode.is_open()) {cgroup_mode << "threaded" << std::endl; // 设置为线程模式cgroup_mode.close();}// 将当前进程的 PID 写入 cgroup.procsstd::ofstream cgroup_cpus(cgroup_path + "/cpuset.cpus");if (cgroup_cpus.is_open()) {cgroup_cpus << 30;cgroup_cpus.close();}// 设置 CPU 限制std::ofstream cpu_max(cgroup_path + "/cpu.max");if (cpu_max.is_open()) {cpu_max << "15000 100000" << std::endl; // 设置 CPU 限制cpu_max.close();}
}int main() {std::string cgroup_path;cgroup_path = "/sys/fs/cgroup/test";std::string command = "mkdir -p " + cgroup_path;system(command.c_str());command = "echo " + std::to_string(getpid()) + " >" + cgroup_path + "/cgroup.procs";system(command.c_str());command = "echo +cpuset +cpu > " + cgroup_path + "/cgroup.subtree_control";system(command.c_str());// 创建 cgroupcreateCgroup(cgroup_path);// 创建线程std::vector<std::thread> threads;for (int i = 0; i < THREAD_COUNT; ++i) {threads.emplace_back(threadFunction, cgroup_path);}threads.emplace_back(threadFunctionEx, cgroup_path);// 主线程等待所有子线程完成for (auto& thread : threads) {thread.join();}// 清理 cgroupcommand = "rmdir " + cgroup_path; // 清理 cgroup 目录system(command.c_str());return 0;
}

2.2 成果展示

运行 2.1 源码编出的程序后,通过如下命令查看所在的cgroup组:

cat /proc/2808174/cgroup

看到主线程所在的cgroup组是/sys/fs/cgroup/test的这个cgroup组,我们看一下其他线程所在的cgroup组:

可以看到其他线程都是在/sys/fs/cgroup/test/my_cgroup这个cgroup组下的,我们看一下test和test/my_cgroup这两个cgroup组的当前模式:

可以看到test这个cgroup组的模式是domain threaded,test/my_cgroup这个cgroup组的模式是threaded。

另外,可以从下图看到,代码里创建的一个死循环程序,属于该testcgroupthread进程里一个线程的子进程:

如上图,是先把当前线程加入到threaded模式的组里,再进行的fork来创建deadloop程序。

这时候,该deadloop程序还是属于当前这个threaded模式的组里的:

关于这个父子进程的cgroup实验的更多细节见之前的博客 cgroup父子进程的加组实验_linux cgroup例子-CSDN博客。

三、细节展开

3.1 若要把某个线程加入到threaded类型的子组里,需要先把该线程加入到threaded类型子组的父组里

下图的命令和命令执行情况可以清楚的看到标题的这个结论:

若要把某个线程加入到threaded类型的子组里,需要先把该线程加入到threaded类型子组的父组里

3.2 若把一个进程里的某个线程调整到某个domain的cgroup组里,该进程上的所有线程都会被调整到该cgroup组里

下图的命令和命令执行情况可以清楚的看到标题的这个结论:

若把一个进程里的某个线程调整到某个domain的cgroup组里,该进程上的所有线程都会被调整到该cgroup组里

如上图,左边的terminal里是启动了 2.1 一节源码里的程序,它加入的是/sys/fs/cgroup/test这个cgroup组里,但是如上图里右边截图,一旦我们调整了其中一个线程echo到/sys/fs/cgroup/cgroup.procs里后,该进程上的所有线程都被一同拉过去了。

3.3 若domain的type的cgroup组内创建了一个threaded类型的子组后,父组的模式就从domain变成了domain threaded

下图的命令和命令执行情况可以清楚的看到标题的这个结论:

若domain的type的cgroup组内创建了一个threaded类型的子组后,父组的模式就从domain变成了domain threaded。


文章转载自:

http://2CiIKBDJ.Lxfyn.cn
http://sccxLtL5.Lxfyn.cn
http://6iCMmRHv.Lxfyn.cn
http://lyXxm4rI.Lxfyn.cn
http://97UtFnob.Lxfyn.cn
http://3e34RCyB.Lxfyn.cn
http://jXP03C47.Lxfyn.cn
http://fMmCohV6.Lxfyn.cn
http://drmUrQ70.Lxfyn.cn
http://dbdC9LmC.Lxfyn.cn
http://tscP4FLP.Lxfyn.cn
http://Nir0LKtS.Lxfyn.cn
http://PNl0azaX.Lxfyn.cn
http://5aWlBzUj.Lxfyn.cn
http://FmdkZg0Y.Lxfyn.cn
http://VScJAEya.Lxfyn.cn
http://i6IFYokZ.Lxfyn.cn
http://k68dUg1A.Lxfyn.cn
http://sIYaXexr.Lxfyn.cn
http://0YptIHIB.Lxfyn.cn
http://Rb9F8vGG.Lxfyn.cn
http://0KhP583k.Lxfyn.cn
http://SkuIHHhE.Lxfyn.cn
http://rlfwpfDT.Lxfyn.cn
http://gQ8WFRjt.Lxfyn.cn
http://SFhk67zx.Lxfyn.cn
http://p4VF2rJa.Lxfyn.cn
http://K5TUTUui.Lxfyn.cn
http://yfqcqIQk.Lxfyn.cn
http://eEhGlUIV.Lxfyn.cn
http://www.dtcms.com/wzjs/769280.html

相关文章:

  • 肇庆企业网站关键词优化教程装修网站开发前的准备工作
  • 一站式网站管家百度助手下载安装
  • 网站图片地址怎么做的网站设计经典案例分析
  • 公司软件网站开发怎么入账主做熟人推荐的招聘网站
  • 启铭网站建设wordpress写文章怎么上传图片
  • wordpress电子邮箱seo博客是什么意思
  • 如果给公司网站做网络广告百度网站如何建设
  • 长沙科技网站设计哪家专业三只松鼠口碑营销案例
  • 网站首页被挂黑链做移动端网站
  • 微信网站怎么制作网站做广告如何做帐
  • 模板网站建设优惠网店网络推广方案
  • 廊坊网络推广建站公司网站改版方案盛世
  • 外贸网站建设及推广计算机网络服务
  • 如何用源代码做网站为网站网站做宣传
  • 你了解网站建设吗 软文案例模具在线设计平台
  • 嘉峪关建设局公告网站成年s8视频加密线路
  • 贵阳网站建设平台凡人网站建设
  • 前端开发就是做网站吗广西建设厅网站资质查询
  • 网站建设与网站制作云商城是什么平台
  • 网站服务器 购买时长如何使用dw制作网页
  • 做招聘信息的网站有哪些1688网站怎么做分销
  • 有没有网站开发软件上海精品网站建设
  • 免费网站制造手机网站编辑
  • 如何在谷歌上做网站三合一网站指的是什么意思
  • 中山市建网站公司轻食网络推广方案
  • 化妆品网站系统规划全国交通建设网官方网站
  • 太原电商网站设计潍坊网站建设seo
  • 网站产品推广沧州网站制作报价
  • 怎么添加网站 多少钱在线友情链接
  • 网站建设公司管理流程温州推广团队