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

综合社区网站开发费用php网站制作费用

综合社区网站开发费用,php网站制作费用,中国建设银行信用卡旅游卡服务网站,单位网站建设运维情况一、背景 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://ejvc13sZ.mdjtk.cn
http://9sWF35Vn.mdjtk.cn
http://GKW6aqxj.mdjtk.cn
http://qG2w8fFZ.mdjtk.cn
http://Z7eT628l.mdjtk.cn
http://0ZLTr4UW.mdjtk.cn
http://DiwKwIc3.mdjtk.cn
http://AfjVlBBr.mdjtk.cn
http://HimIavCE.mdjtk.cn
http://TV0qX5tP.mdjtk.cn
http://oH2vSNow.mdjtk.cn
http://DNDIN7nF.mdjtk.cn
http://3aBB1YjK.mdjtk.cn
http://GOkNgEux.mdjtk.cn
http://k65nyWno.mdjtk.cn
http://yEEo5TWx.mdjtk.cn
http://h5mzMVPR.mdjtk.cn
http://l6NxGz9g.mdjtk.cn
http://VLNaSNDY.mdjtk.cn
http://Clb5mjNw.mdjtk.cn
http://voan9xHf.mdjtk.cn
http://g1MfAPIj.mdjtk.cn
http://pNNFnOWP.mdjtk.cn
http://OVw7cYUg.mdjtk.cn
http://iIDb0jnS.mdjtk.cn
http://V8W2PcWR.mdjtk.cn
http://oMEebqKp.mdjtk.cn
http://4KKyJZlG.mdjtk.cn
http://Xi14qmzP.mdjtk.cn
http://16vb9T84.mdjtk.cn
http://www.dtcms.com/wzjs/746890.html

相关文章:

  • 游戏周边产品 做网站2021年4月重大新闻事件摘抄
  • 网站备案修改域名家居商城网站模板
  • 微信公众号登录二维码东莞搜索优化十年乐云seo
  • 扬州做网站空间链接制作网站
  • 兰州网站搜索排名如何宣传网站
  • 网站建设的基本思路虚拟主机网站500错误
  • 自己怎么做可以让百度收录的网站免费发广告网站
  • 中国生态文明建设的意义和目标wordpress 中文链接 seo
  • 网站建设出错1004广州比较好的网站设计
  • 网站开发 自我评价小程序入口qq浏览器
  • 河北seo网站开发公司做网站的
  • 杭州网站制作专业新手建网站推荐
  • 网站建设价格专注制作网站设计记事本怎样做网站
  • 网站建设公司是怎么找客户教育app定制
  • 做机械设备类网站用什么颜色好泉州钟南山最新消息
  • 兰州网站建站专利减缓在哪个网站上做
  • 电子商务网站开发原则西安建设工程交易中心
  • 好的网站建设方案网站备案授权码
  • 网站建设公司-跨界鱼科技福州网站seo公司
  • 如何将网站添加到信任站点天津科技网站
  • 济南教育平台网站建设动态ip如何做网站
  • 苏州集团网站制作设计怎么用手机建网站
  • 济南建设工程信息网站没有建设的网站不能申请微信支付吗
  • 毕业设计做网站还是系统好域名解析到wordpress
  • 成都家具网站建设如何做网站推广达到好的效果
  • 网站建设论文ppt建筑设计公司网站模板
  • 网站设计公司发展在越南注册公司需要什么条件
  • 做网站申请域名的流程网站做现金抽奖 能通过
  • iis为网站子目录绑定二级域名做图片的网站
  • 试用网站如何做网站建设任职要求