cgroup

简介: 创建两个python进程,然后分别绑定在第0,1号CPU上.

先做一个小实验

创建两个python进程,然后分别绑定在第0,1号CPU上.

创建cpuset的cgroup

➜  /    mkdir -p /cgroup/cpuset1 
➜  /    mount -t cgroup -o cpuset cpuset1 /cgroup/cpuset1 
➜  /  ls /cgroup/cpuset1/
cgroup.clone_children  cpuset.effective_cpus  cpuset.memory_pressure          cpuset.sched_load_balance
cgroup.procs           cpuset.effective_mems  cpuset.memory_pressure_enabled  cpuset.sched_relax_domain_level
cgroup.sane_behavior   cpuset.mem_exclusive   cpuset.memory_spread_page       notify_on_release
cpuset.cpu_exclusive   cpuset.mem_hardwall    cpuset.memory_spread_slab       release_agent
cpuset.cpus            cpuset.memory_migrate  cpuset.mems                     tasks

创建python进程

➜  /  echo 'while True:    pass' | python &
[1] 19983 19985
➜  /  echo 'while True:    pass' | python &
[2] 20006 20012

通过cgrup的cpuset子系统绑定cpu

绑定第一个python进程

mkdir /cgroup/cpuset1/foo1
   echo 0 > /cgroup/cpuset1/foo1/cpuset.mems
   echo 0 > /cgroup/cpuset1/foo1/cpuset.cpus
   echo 20012 > /cgroup/cpuset1/foo1/tasks
   其中,
       cpuset.mems是绑定内存节点,参见NUMA.
       cpuset.cpus是绑定cpu

绑定第二个python进程

mkdir /cgroup/cpuset1/foo1
   echo 0 > /cgroup/cpuset1/foo1/cpuset.mems
   echo 1 > /cgroup/cpuset1/foo1/cpuset.cpus
   echo 19985 > /cgroup/cpuset1/foo1/tasks

绑定效果

image.png

cgroup 是如何在系统中生效的?

cgroup是通过文件系统VFS的接口在内核中生效的.

cgroup的术语

cgroup

关联一组task和一组subsystem的配置参数。一个task对应一个进程, cgroup是资源分片的最小单位。cgroup是树状组织起来.

subsystem

资源管理器,一个subsystem对应一项资源的管理,如 cpu, cpuset, memory, blkio, ns, net_cls等.

hierarchy

关联一个到多个subsystem和一组树形结构的cgroup.
和cgroup不同,hierarchy包含的是可管理的subsystem而非具体参数.

总结

cgroup对资源的管理是一个树形结构,类似进程。子cgroup继承父cgroup.
但是, cgroup可以有多个根,每mount一次都有一个根.

进程和cgroup的关系

image.png

cgroup mount进kernel的过程

mount -t cgroup -o cpuset cpuset1 /cgroup/cpuset1
-t, 指定了文件系统的类型是cgroup.
    -o, 指定了子系统是cpuset, 这个字符串会一直传给具体的文件系统解析函数.

cgroup文件系统的注册

kernel在启动过程中会注册,并且初始化cgroup文件系统.

调用栈:

asmlinkage void __init start_kernel(void) {
        cgroup_init();
    }
    int __init cgroup_init(void) {
        for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
                struct cgroup_subsys *ss = subsys[i];
                if (!ss->early_init)
                        cgroup_init_subsys(ss);
                if (ss->use_id)
                        cgroup_subsys_init_idr(ss);
        }
        err = register_filesystem(&cgroup_fs_type);
        hhead = css_set_hash(init_css_set.subsys);
    }

其中,

static struct file_system_type cgroup_fs_type = {
        .name = "cgroup",
        .get_sb = cgroup_get_sb,
        .kill_sb = cgroup_kill_sb,
    };

cgroup的super block

static int cgroup_get_sb(struct file_system_type *fs_type,
                         int flags, const char *unused_dev_name,
                         void *data, struct vfsmount *mnt)
{
    // 解析 "-o cpuset"
    ret = parse_cgroupfs_options(data, &opts);
    // 分配一个 cgroupfs_root
    // 注意,如果是mount一个已经被mount过了的子系统, 则通用一个cgroupfs_root.
    // 也就是说, 此时对其中一个操作,另一个会看到同样的视图.好比,一块磁盘被rebind了.
    new_root = cgroup_root_from_opts(&opts);
    // 分配一个super block, 或者服用已经有的.
    sb = sget(fs_type, cgroup_test_super, cgroup_set_super, &opts);
    // 分配 link
    ret = allocate_cg_links(css_set_count, &tmp_cg_links);
    // 绑定指定的子系统到新的cgroupfs_root上
    ret = rebind_subsystems(root, root->subsys_bits);
    sb->s_root->d_fsdata = root_cgrp;
    root->top_cgroup.dentry = sb->s_root;
    // 将现存的所有的css_set挂入到新的cgroup中
    for (i = 0; i < CSS_SET_TABLE_SIZE; i++) {
        struct hlist_head *hhead = &css_set_table[i];
        struct hlist_node *node;
        struct css_set *cg;
        hlist_for_each_entry(cg, node, hhead, hlist)
                link_css_set(&tmp_cg_links, cg, root_cgrp);
    }
    // 生成虚拟的文件
    cgroup_populate_dir(root_cgrp);
相关文章
|
Ubuntu 前端开发 Linux
通过Ftrace实现高效、精确的内核调试与分析(上)
通过Ftrace实现高效、精确的内核调试与分析
|
网络协议 Linux 数据库
|
8月前
|
数据建模 网络安全
阿里云ssl证书价格一年多少钱?2025年最新收费标准,有免费版申请
阿里云SSL证书2025年最新收费标准:免费版为Digicert品牌,有效期3个月;付费DV证书最低68元/年起,如WoSign单域名OV仅238元/年,DigiCert通配符DV优惠价1500元/年,GlobalSign OV企业型1864元/年。新用户享DV证书5折起,全系列75折起,正式环境建议选用付费证书。
|
运维 Kubernetes 调度
【kubernetes】关于k8s集群的污点、容忍、驱逐以及k8s集群故障排查思路
【kubernetes】关于k8s集群的污点、容忍、驱逐以及k8s集群故障排查思路
2099 156
|
存储 Kubernetes API
在K8S中,Kubernetes的组件有哪些?
在K8S中,Kubernetes的组件有哪些?
|
缓存 网络协议 Unix
Linux 内核参数
Linux 内核参数
854 1
|
资源调度 Kubernetes 应用服务中间件
Deployment的创建、滚动更新、回滚版本、扩容缩容
Deployment的创建、滚动更新、回滚版本、扩容缩容
744 1
|
存储 定位技术 对象存储
阿里云对象存储OSS外网流出流量异常增多导致费用上升的解决方法
阿里云对象存储OSS外网流出流量异常增多导致费用上升的解决方法
1501 2
阿里云对象存储OSS外网流出流量异常增多导致费用上升的解决方法
|
安全 Java 开发者
Python中的多线程高级使用方法
**Python多线程高级指南摘要** 本文探讨了Python中多线程的高级技术,尽管GIL限制了并行执行,但多线程仍适用于IO密集型任务和提升UI响应。内容包括: - 使用`threading`模块导入和创建线程,示例展示了如何启动多个线程执行函数。 - 高级用法涉及线程池,通过`ThreadPoolExecutor`管理线程,简化大量线程的创建和控制。 - 线程同步:介绍锁和条件变量的概念,以及如何使用它们确保数据一致性。 - 避免死锁的策略,如使用`try/finally`确保锁的正确释放 - 线程局部数据(Thread Local Data)允许每个线程拥有独立的数据副本,避免冲突
624 0

热门文章

最新文章