如何限制每个用户可以使用的 CPU 内核数量?

Rez*_*eza 24 permissions administration users multi-core

我们有一台 CPU 有 32 个内核的计算机,它将被几个不同的用户用来运行程序。有什么办法可以限制每个用户在任何时候可以使用的核心数,这样一个用户就不会独占所有的CPU功率吗?

ter*_*don 20

虽然这是可能的,但它很复杂,而且几乎肯定是个坏主意。如果此时只有一个用户在使用机器,将他们限制为 N 个内核是一种资源浪费。更好的方法是使用以下命令运行所有内容nice

NAME
       nice - run a program with modified scheduling priority

SYNOPSIS
       nice [OPTION] [COMMAND [ARG]...]

DESCRIPTION
       Run  COMMAND  with an adjusted niceness, which affects process scheduling.  With
       no COMMAND, print the current niceness.  Niceness values range  from  -20  (most
       favorable to the process) to 19 (least favorable to the process).
Run Code Online (Sandbox Code Playgroud)

这是一个很好的工具,可以设置进程的优先级。因此,如果只有一个用户正在运行某些东西,他们将获得所需的 CPU 时间,但如果其他人启动他们自己的(也不错的)作业,他们会很友好并相互分享。这样,如果您的用户都使用 启动命令nice 10 command,则没有人会占用资源(也没有人会使服务器屈服)。

请注意,高 nice 值意味着低优先级。这是衡量我们应该有多好的衡量标准,我们越好,我们分享的就越多。

另请注意,这无助于管理内存分配,只会影响 CPU 调度。因此,如果多个用户启动多个内存密集型进程,您仍然会遇到问题。如果这是一个问题,您应该研究适当的排队系统,例如扭矩

  • @Reza:那是因为操作系统已经这样做了。它会根据需要自动将可用 CPU 时间共享给线程/进程。 (3认同)

Ser*_*nyy 16

TL;DR:从简短的研究来看,似乎可以将命令限制到特定数量的内核,但是在所有情况下,您都必须使用实际执行限制的命令。

群组

Linuxcgroups经常使用它来限制进程可用的资源。从一个非常简短的研究中,您可以在 Arch Wiki 中找到一个示例,其中设置了 Matlab(一种科学软件)配置/etc/cgconfig.conf

group matlab {
    perm {
        admin {
            uid = username;
        }
        task {
            uid = username;
        }
    }

    cpuset {
        cpuset.mems="0";
        cpuset.cpus="0-5";
    }
    memory {
        memory.limit_in_bytes = 5000000000;
    }
}
Run Code Online (Sandbox Code Playgroud)

为了使此类配置生效,您必须通过cgexec命令运行该过程,例如从同一个 wiki 页面:

$ cgexec -g memory,cpuset:matlab /opt/MATLAB/2012b/bin/matlab -desktop
Run Code Online (Sandbox Code Playgroud)

任务集

关于询问 Ubuntu 和如何在 Linux 中将进程限制为一个 CPU 内核相关问题?[重复]在 Unix&Linux 站点上显示了一个taskset用于限制进程 CPU的示例。在第一个问题中,它是通过解析特定用户的所有进程来实现的

$ ps aux | awk '/^housezet/{print $2}' | xargs -l taskset -p 0x00000001
Run Code Online (Sandbox Code Playgroud)

在另一个问题中,进程是通过taskset自身启动的:

$ taskset -c 0 mycommand --option  # start a command with the given affinity
Run Code Online (Sandbox Code Playgroud)

结论

虽然当然可以限制进程,但对于特定用户来说,实现这一点似乎并不那么简单。链接的 Ask Ubuntu 帖子中的示例需要对属于每个用户的进程进行一致的扫描,并taskset在每个新用户上使用。更合理的方法是通过cgexec或有选择地运行 CPU 密集型应用程序taskset;将所有进程限制在特定数量的 CPU 上也是没有意义的,特别是对于那些实际上利用并行性和并发性来更快地运行任务的进程 - 将它们限制在特定数量的 CPU 上可能会降低处理速度。此外,正如terdon 的回答所说,这是一种资源浪费

通过taskset或运行选择的应用程序cgexec需要与您的用户沟通,让他们知道他们可以运行哪些应用程序,或者创建将通过tasksel或启动选择的应用程序的包装器脚本cgexec

此外,请考虑设置用户或组可以生成的进程数,而不是设置 CPU 数限制。这可以通过/etc/security/limits.conf文件来实现。

也可以看看

  • [`sched_setaffinity(2)`](http://man7.org/linux/man-pages/man2/sched_setaffinity.2.html) 说在 `execve(2)` 中保留了亲和掩码,*并且* child 在`fork(2)` 上继承它。因此,如果您为用户设置 shell(或为 X 会话设置他们的图形 shell),默认情况下,他们从该 shell 启动的所有内容都将使用相同的关联掩码。 (2认同)