探究如何在Linux系统中修改进程资源限制:四种方法调整进程限制,让你的系统高效运行(包含应用层getrlimit和setrlimit API)

简介: 探究如何在Linux系统中修改进程资源限制:四种方法调整进程限制,让你的系统高效运行(包含应用层getrlimit和setrlimit API)


摘要:本文将详细介绍如何在Linux系统中修改进程资源限制,帮助您掌握一些关键技术,从而更好地管理和优化系统资源。文章内容将涵盖基本概念、方法和实践示例。

一、简介

1.进程资源限制的概念

在Linux系统中,进程资源限制是一种管理策略,用于控制进程使用系统资源的上限。这种机制可以防止某个进程占用过多资源,从而影响其他进程的正常运行。进程资源限制包括CPU时间、内存、打开文件数等多种资源类型。

2.修改进程资源限制的意义与应用场景

修改进程资源限制具有以下几个意义:

a. 系统资源管理:通过对进程资源的限制,管理员可以更好地对系统资源进行分配与管理,确保关键进程获得足够的资源,防止低优先级进程占用过多资源。

b. 提高系统稳定性:限制进程资源能有效避免资源耗尽,从而防止系统崩溃。

c. 提高应用性能:合理分配资源,避免资源竞争,可以在一定程度上提高应用的性能。


常见的应用场景有:

  • 多用户环境中限制单个用户占用资源
  • 服务器上限制不同服务的资源使用,以避免某个服务耗尽系统资源
  • 开发环境中限制开发人员的测试程序对系统资源的使用

Linux中的资源限制

1.软限制与硬限制

在Linux系统中,进程资源限制分为软限制(soft limit)和硬限制(hard limit)两种。

  • 软限制:这是进程实际受到的资源限制。当进程试图超过这个限制时,系统通常会产生一个警告,但不会强制终止进程。软限制可以在需要时被提高,但不能超过硬限制。
  • 硬限制:这是进程资源限制的最大值,一旦达到这个限制,进程将无法继续申请更多资源。硬限制只能由具有特权的用户(如root用户)修改。

2.常见资源限制类型

以下是Linux系统中常见的进程资源限制类型:

  • CPU时间(cpu time):进程可以使用的CPU时间的最大值。
  • 内存使用(memory usage):进程可以使用的最大内存量。
  • 打开文件数(open files):进程可以同时打开的文件数量上限。
  • 并发线程数(threads):进程可以创建的最大线程数。
  • 进程数(processes):用户可以创建的最大进程数。
  • 栈大小(stack size):进程栈的最大大小。
  • 数据段大小(data segment size):进程数据段的最大大小。
  • 锁定内存大小(locked memory):进程可以锁定的内存大小。
    这些限制可以单独或组合使用,以实现更精细的资源管理。在接下来的部分,我们将介绍如何在Linux中修改这些进程资源限制。


Linux中的资源限制

1.ulimit命令

a. 语法及选项

ulimit命令是一个常用的shell内置命令,用于查看和设置进程资源限制。ulimit的基本语法如下:

ulimit [-HS] [-a] [-t] [-f] [-d] [-s] [-c] [-m] [-l] [-p] [-n] [limit]

常用选项说明:


-H:设置或显示硬限制。

-S:设置或显示软限制。

-a:显示所有资源限制。

-t:设置或显示CPU时间限制。

-f:设置或显示文件大小限制。

-d:设置或显示数据段大小限制。

-s:设置或显示栈大小限制。

-c:设置或显示核心文件大小限制。

-m:设置或显示内存使用限制。

-l:设置或显示锁定内存大小限制。

-p:设置或显示进程数限制。

-n:设置或显示打开文件数限制。

b. 示例与应用


查看当前进程的所有资源限制:

ulimit -a

设置当前进程的打开文件数限制为2048(软限制):

ulimit -Sn 2048

设置当前进程的CPU时间限制为3600秒(硬限制):

ulimit -Ht 3600

/etc/security/limits.conf配置文件


2./etc/security/limits.conf配置文件

a. 配置文件结构

/etc/security/limits.conf是一个全局配置文件,用于设置系统范围内的用户和用户组资源限制。配置文件的每一行表示一个限制规则,包含四个字段:用户或用户组名、限制类型(硬限制或软限制)、资源类型和限制值。

b.示例与应用

为用户alice设置最大打开文件数限制(硬限制为4096,软限制为2048):

alice       hard    nofile    4096
alice       soft    nofile    2048

为用户组developers设置最大进程数限制(硬限制为1024,软限制为512):

@developers hard    nproc     1024
@developers soft    nproc     512

3. 使用cgroups(控制组)

a. cgroups简介

cgroups(Control Groups)是Linux内核中的一项功能,用于对进程进行分组管理和限制。cgroups可以实现对CPU、内存、磁盘I/O等资源的细粒度控制,提供更强大的资源管理能力。
cgroups通过文件系统(通常挂载在/sys/fs/cgroup目录下)的方式对资源限制进行配置,支持动态调整和实时监控。此外,cgroups还支持多层次的进程组织结构,可以根据不同的应用场景设定不同级别的资源限制。

b. 设置cgroups资源限制

要使用cgroups设置资源限制,请按照以下步骤操作:
检查系统是否支持cgroups:运行lssubsys -a命令,查看系统支持的cgroup子系统。
创建cgroup:创建一个新的cgroup,以便将进程添加到该组并限制其资源。例如,创建一个名为my_cgroup的cgroup,可以在/sys/fs/cgroup/cpu目录下创建一个名为my_cgroup的子目录。

c. 示例与应用

控制组(cgroups)是一种Linux内核功能,可以限制、记录和隔离进程的资源使用。管理员可以使用cgroups来管理进程的CPU、内存、磁盘和网络等资源,从而提高系统性能和安全性。下面是一个使用cgroups修改进程资源的示例:


创建控制组

首先,我们需要创建一个控制组,用于管理要限制的进程。可以使用以下命令来创建一个名为mygroup的控制组:


sudo cgcreate -g cpu,memory:/mygroup

这将创建一个包含CPU和内存子系统的控制组/mygroup。


添加进程到控制组

接下来,我们需要将要限制的进程添加到控制组中。可以使用以下命令将pid为1234的进程添加到mygroup控制组中:


sudo cgclassify -g cpu,memory:/mygroup 1234

这将将进程1234添加到/mygroup控制组中。


限制资源使用

现在,我们可以使用cgroups来限制进程的资源使用。例如,可以使用以下命令将mygroup控制组中的进程的CPU使用率限制为50%!:(MISSING)


sudo cgset -r cpu.cfs_quota_us=50000 mygroup

这将限制mygroup控制组中的进程使用50%!的(MISSING)CPU时间。类似地,我们可以使用其他选项来限制内存、磁盘和网络资源的使用。


监控资源使用

最后,我们可以使用cgroups来监控进程的资源使用。例如,可以使用以下命令查看mygroup控制组中进程的CPU使用情况:


sudo cgget -r cpuacct.usage mygroup

这将显示mygroup控制组中所有进程的CPU使用时间。


总之,cgroups是Linux系统中一个非常有用的功能,可以用于限制、记录和隔离进程的资源使用。管理员可以使用cgroups来管理进程的CPU、内存、磁盘和网络等资源,从而提高系统性能和安全性。使用cgroups可以灵活地控制进程的资源使用和监控,从而更好地管理系统和进程。

4. 应用层使用getrlimit和setrlimit API

功能描述

获取或设定资源使用限制。每种资源都有相关的软硬限制,软限制是内核强加给相应资源的限制值,硬限制是软限制的最大值。非授权调用进程只可以将其软限制指定为0~硬限制范围中的某个值,同时能不可逆转地降低其硬限制。授权进程可以任意改变其软硬限制。RLIM_INFINITY的值表示不对资源限制。

函数原型

#include <sys/resource.h>
int getrlimit(int resource, struct rlimit \*rlim);
int setrlimit(int resource, const struct rlimit \*rlim);

参数:

resource:可能的选择有以下几种

RLIMIT_AS //进程的最大虚内存空间,字节为单位。

RLIMIT_CORE //内核转存文件的最大长度。

RLIMIT_CPU //最大允许的CPU使用时间,秒为单位。当进程达到软限制,内核将给其发送SIGXCPU信号,这一信号的默认行为是终止进程的执行。然而,可以捕捉信号,处理句柄可将控制返回给主程序。如果进程继续耗费CPU时间,核心会以每秒一次的频率给其发送SIGXCPU信号,直到达到硬限制,那时将给进程发送 SIGKILL信号终止其执行。

RLIMIT_DATA //进程数据段的最大值。

RLIMIT_FSIZE //进程可建立的文件的最大长度。如果进程试图超出这一限制时,核心会给其发送SIGXFSZ信号,默认情况下将终止进程的执行。

RLIMIT_LOCKS //进程可建立的锁和租赁的最大值。

RLIMIT_MEMLOCK //进程可锁定在内存中的最大数据量,字节为单位。

RLIMIT_MSGQUEUE //进程可为POSIX消息队列分配的最大字节数。

RLIMIT_NICE //进程可通过setpriority() 或 nice()调用设置的最大完美值。

RLIMIT_NOFILE //指定比进程可打开的最大文件描述词大一的值,超出此值,将会产生EMFILE错误。

RLIMIT_NPROC //用户可拥有的最大进程数。

RLIMIT_RTPRIO //进程可通过sched_setscheduler 和 sched_setparam设置的最大实时优先级。

RLIMIT_SIGPENDING //用户可拥有的最大挂起信号数。

RLIMIT_STACK //最大的进程堆栈,以字节为单位。

rlim:描述资源软硬限制的结构体,原型如下

struct rlimit {
  rlim\_t rlim\_cur;  //soft limit
  rlim\_t rlim\_max;  //hard limit
};

soft limit是指内核所能支持的资源上限。比如对于RLIMIT_NOFILE(一个进程能打开的最大文件数,内核默认是1024),soft limit最大也只能达到1024。对于RLIMIT_CORE(core文件的大小,内核不做限制),soft limit最大能是unlimited。

hard limit在资源中只是作为soft limit的上限。当你设置hard limit后,你以后设置的soft limit只能小于hard limit。要说明的是,hard limit只针对非特权进程,也就是进程的有效用户ID(effective user ID)不是0的进程。具有特权级别的进程(具有属性CAP_SYS_RESOURCE),soft limit则只有内核上限。

返回说明

成功执行时,返回0。

失败返回-1,errno被设为以下的某个值

EFAULT:rlim指针指向的空间不可访问

EINVAL:参数无效

EPERM:增加资源限制值时,权能不允许

示例

当我们需要在Linux系统中修改进程资源限制时,可以使用getrlimit和setrlimit API来设置资源限制。下面是一个使用getrlimit和setrlimit API修改系统资源的示例:

#include <sys/resource.h>
#include <iostream>
#include <cstring>
int main() {
    const rlim_t kStackSize = 64 * 1024 * 1024;   // 64MB
    struct rlimit rl;
    int result;
    // 获取当前的资源限制
    result = getrlimit(RLIMIT_STACK, &rl);
    if (result == -1) {
        std::cerr << "Failed to get resource limit\n";
        return 1;
    }
    // 修改资源限制
    if (rl.rlim_cur < kStackSize) {
        rl.rlim_cur = kStackSize;
        result = setrlimit(RLIMIT_STACK, &rl);
        if (result == -1) {
            std::cerr << "Failed to set resource limit\n";
            return 1;
        }
    }
    // 执行需要大内存栈的代码
    char largeStack[kStackSize];
    std::memset(largeStack, 0, kStackSize);
    return 0;
}

在这个示例中,我们将栈大小的资源限制设置为64MB(kStackSize),然后使用getrlimit和setrlimit API来修改这个资源限制。首先,我们使用getrlimit函数来获取当前栈大小的资源限制。然后,我们检查当前资源限制是否小于我们需要的资源大小。如果当前资源限制小于我们需要的资源大小,我们使用setrlimit函数来修改栈大小的资源限制。
最后,在我们需要大内存栈的代码块中,我们分配了64MB的内存。
总之,使用getrlimit和setrlimit API来修改系统资源是Linux C++编程中的一个重要技能,可以帮助我们优化系统资源使用。在使用这些API时,我们需要了解当前的资源限制,修改需要的资源限制,并在修改后检查资源限制是否生效。


四、实战篇:优化系统资源管理

在Linux系统中,管理员可以使用控制组(cgroups)和其他工具来优化系统资源管理,从而提高系统性能和可靠性。以下是一些实战篇的建议:

识别资源瓶颈

首先,管理员需要了解系统中存在的资源瓶颈,例如CPU、内存、磁盘和网络等。可以使用一些工具,如top、htop、iostat和vmstat等,来了解系统资源的使用情况。管理员可以在这些工具中查看CPU、内存、磁盘和网络等方面的数据,以确定系统资源瓶颈所在。

调整不同进程的资源限制

管理员可以使用cgroups来调整不同进程的资源限制,以确保系统资源的平衡使用。例如,可以将CPU和内存等资源分配给不同的进程,以避免某个进程占用过多的资源,导致其他进程受到影响。可以使用一些工具,如cgcreate、cgclassify和cgset等,来创建控制组、添加进程和设置资源限制。

监控资源使用情况

管理员需要定期监控系统资源使用情况,以确保资源使用保持平衡。可以使用一些工具,如cgget、top、htop、iostat和vmstat等,来监控系统资源的使用情况。管理员可以在这些工具中查看CPU、内存、磁盘和网络等方面的数据,以确保资源使用情况正常。

避免资源耗尽

最后,管理员需要避免系统资源耗尽,以确保系统的可靠性和稳定性。可以使用一些策略,如动态资源分配、资源预留和资源回收等,来避免资源耗尽。例如,可以根据系统负载情况动态分配资源,预留资源给关键进程,以及回收不需要的资源等。
总之,优化系统资源管理是Linux系统管理中一个非常重要的任务。管理员可以使用控制组和其他工具来调整进程的资源限制,监控资源使用情况,避免资源耗尽等,以确保系统资源使用平衡和系统的可靠性。


五、注意事项

在Linux系统中修改进程资源限制时,需要注意以下几个方面:
确认当前的资源限制
在修改进程资源限制之前,需要确认当前的资源限制。可以使用命令ulimit -a来查看当前的资源限制。
确认修改的范围
在修改进程资源限制之前,需要确认修改的范围。可以使用命令ulimit -a -H和ulimit -a -S来查看硬限制和软限制,以便确认修改的范围。
确认修改的值
在修改进程资源限制之前,需要确认修改的值。可以使用cgroups和其他工具,如getrlimit和setrlimit API,来设置资源限制。
确认修改的持久性
在修改进程资源限制之后,需要确认修改的持久性。可以使用/etc/security/limits.conf配置文件来设置永久性的资源限制。
确认修改的影响
在修改进程资源限制之后,需要确认修改的影响。可以使用一些工具,如top、htop、iostat和vmstat等,来监控系统资源的使用情况,以确保资源使用情况正常。
总之,在Linux系统中修改进程资源限制时,需要确认当前的资源限制、修改的范围、修改的值、修改的持久性和修改的影响。可以使用多种工具来修改进程资源限制,如ulimit命令、/etc/security/limits.conf配置文件、cgroups和getrlimit和setrlimit API等。


目录
相关文章
|
4天前
|
存储 负载均衡 Linux
【Linux 系统】进程间通信(匿名管道 & 命名管道)-- 详解(下)
【Linux 系统】进程间通信(匿名管道 & 命名管道)-- 详解(下)
|
4天前
|
消息中间件 Unix Linux
【Linux 系统】进程间通信(匿名管道 & 命名管道)-- 详解(上)
【Linux 系统】进程间通信(匿名管道 & 命名管道)-- 详解(上)
|
4天前
|
缓存 Linux 调度
【Linux 系统】进程控制 -- 详解
【Linux 系统】进程控制 -- 详解
|
4天前
|
Shell Linux 程序员
【Linux】Shell 命令以及运行原理
【Linux】Shell 命令以及运行原理
|
4天前
|
存储 Unix Linux
【Linux 系统】进程信号 -- 详解(下)
【Linux 系统】进程信号 -- 详解(下)
|
4天前
|
NoSQL Linux Shell
【Linux 系统】进程信号 -- 详解(上)
【Linux 系统】进程信号 -- 详解(上)
|
4天前
|
消息中间件 存储 安全
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(下)
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(下)
|
4天前
|
消息中间件 算法 Linux
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(上)
【Linux 系统】进程间通信(共享内存、消息队列、信号量)(上)
|
11天前
|
Linux API
Linux系统编程之文件编程常用API回顾和文件编程一般步骤
Linux系统编程之文件编程常用API回顾和文件编程一般步骤
Linux系统编程之文件编程常用API回顾和文件编程一般步骤
|
11天前
ps 查看当前系统进程状态
【5月更文挑战第7天】ps 查看当前系统进程状态。
18 5