APUE学习之进程资源限制

目录

一、进程资源限制

 二、getrlimit()和setrlimit函数

 1、参数说明

 2、代码演示

3、注意事项


如果对多进程编程不熟悉的同学,推荐先看看《APUE学习之多进程编程》这篇文章。通过多进程编程的学习,我们可以使用多进程来实现多个客户端的并发,那是不是一个服务器可以给无限多个客户端提供服务呢?让我们一起带着这个疑问往下学习吧!

一、进程资源限制

首先,一个服务器肯定是不能给无限多个客户端提供服务。因为Linux下每种资源都有相关的软硬限制,譬如单个用户最多能创建的子进程个数有限制,同样一个进程最多能打开的文件描述符也有相应的限制值,这些限制会限制服务器能够提供并发访问的客户端的数量。

那么,为什么要有进程资源限制呢?

在多用户环境下,系统资源的分配和管理是至关重要的。进程资源限制的引入是为了解决以下问题:

  • 资源公平分配: 防止一个进程过度占用系统资源,影响其他进程的正常运行。
  • 系统稳定性: 通过限制某些资源的使用,可以防止因为某个进程的失控使用而导致整个系统崩溃。
  • 安全性: 防止一些恶意程序通过大量资源占用进行拒绝服务(DoS)攻击。 

Unix系统提供了多种资源限制,常见的资源类型包括:

  • CPU时间: 控制进程在CPU上运行的时间。
  • 内存: 限制进程可用的物理内存和虚拟内存。
  • 文件描述符: 控制进程能够同时打开的文件数量。
  • 进程数: 限制系统中的进程数量。
  • 网络带宽: 通过cgroups限制进程的网络资源使用。
  • 磁盘IO: 限制进程对磁盘的读写速度。

 二、getrlimit()和setrlimit函数

在Linux系统下,我们可以使用下面两个函数来获取或设置相应的限制:

#include 

int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);

 1、参数说明

(1)resource

这个参数指定了要获取限制信息的资源类型。不同的资源类型由不同的常量表示,常见的资源类型包括:

  • RLIMIT_CORE:内核转储文件的最大长度。
  • RLIMIT_AS:进程的最大虚内存空间。
  • RLIMIT_CPU:最大允许的CPU使用时间。当进程达到软限制,内核将其发送SIGXCPU信号,这一信号的默认行为是终止进程的执行。
  • RLIMIT_DATA:进程数据段的最大值。
  • RLIMIT_FSIZE:进程可建立的文件的最大长度。如果进程试图超出这一限制时,内核会给其发送SIDXFSZ信号,默认情况下将终止进程的执行。
  • RLIMIT_NOFILE每个进程能打开的最多文件数
  • RLIMIT_NPROC用户可拥有的最大进程数
  • RLIMIT_STACK:最大的进程堆栈。

(2)rlim

这个参数是一个指向 struct rlimit 结构体的指针。struct rlimit 结构体用于存储获取到的资源限制信息。结构体的定义如下:

struct rlimit {

    rlim_t rlim_cur;  // Soft limit:current limit
    rlim_t rlim_max;  // Hard limit:maximum value for rlim_cur
};
  • rlim_cur 表示软限制,即资源的当前限制值。
  • rlim_max 表示硬限制,即资源的最大限制值。

 2、代码演示

#include 
#include 
#include 
#include 

void print_limits(char *name,int resource)
{

        struct rlimit           limit;

        if( getrlimit( resource,&limit ) < 0 )
        {

                printf("getrlimit failure:%s\n",strerror(errno));
                return ;

        }

        printf("%-15s",name);

        //判断软限制是否无限(软限制值必须小于硬限制值)
        if( limit.rlim_cur == RLIM_INFINITY )
        {

                printf("(infinite)      ");

        }
        else
        {

                printf("%-15ld",limit.rlim_cur);

        }

         //判断硬限制是否无限
        if( limit.rlim_max == RLIM_INFINITY )
        {

                 printf("(infinite)      ");

        }
        else
        {

                printf("%-15ld",limit.rlim_max);

        }

        printf("\n");

}

int main(void)
{

        struct rlimit           limit = {0};

        print_limits("RLIMIT_NPROC",RLIMIT_NPROC);
        print_limits("RLIMIT_DATA",RLIMIT_DATA);
        print_limits("RLIMIT_STACK",RLIMIT_STACK);
        print_limits("RLIMIT_NOFILE",RLIMIT_NOFILE);

        printf("\nAfter set RLIMIT_NOFILE:\n");/*将软限制设为最大限制*/

        getrlimit(RLIMIT_NOFILE,&limit);
        limit.rlim_cur = limit.rlim_max;
        setrlimit(RLIMIT_NOFILE,&limit);

        print_limits("RLIMIT_NOFILE",RLIMIT_NOFILE);

        return 0;

}

APUE学习之进程资源限制_第1张图片

看代码运行结果,注意RLIMIT_NOFILE修改前后的区别。

3、注意事项

在更改资源限制的时候,必须遵守以下3点原则:

(1)任何一个进程都可以将一个软限制值更改为小于或等于其硬限制值。

(2)任何一个进程都可降低其硬限制值,但它必须大于或等于其软限制值。这种降低,对普通用户而言是不可逆的。

(3)只有超级用户进程可以提高硬限制值

Unix编程中的进程资源限制是系统管理和开发中的重要概念。通过灵活地使用 getrlimit 和 setrlimit 等系统调用,开发者可以精确控制进程对系统资源的访问,从而提高系统的稳定性和安全性。深入理解和应用这些资源限制机制,将有助于编写更健壮、高效的Unix应用程序。

你可能感兴趣的:(APUE,学习,unix,linux)