一、前言
一个进程在运行时,会用到各种资源,比如cpu的使用时间、内存空间、文件等等。那么,一个进程能够占用多少资源呢?cpu使用的时间有多长?进程空间有多大?能够创建多少个文件?这个就是本文需要讨论的内容。
unix系统提供了两个函数来查询和修改进程的资源限制:getrlimit、setrlimit
本文将围绕这两个函数展开讨论。
二、getrlimit
getrlimit用于查看一个进程的资源限制,其函数原型如下:
头文件:#include <sys/resource.h>
函数原型: int getrlimit(int resource, struct rlimit *rlim);
resource参数指定要查询的资源类型,比如RLIMIT_CPU(CPU时间限制)、RLIMIT_FSIZE(文件大小限制)等。
rlim是指向rlimit结构的指针,该结构用于填充查询到的限制值。 如果调用成功,getrlimit返回0。
返回值: 如果调用失败,返回-1,并且设置errno以指示错误类型。 常见的错误可能包括:
EINVAL: 指定的resource参数无效。
EPERM: 用户没有权限获取指定资源的限制。 ENOMEM: 内存不足,无法完成请求。
rlimit数据结构的定义如下:
struct rlimit {
rlim_t rlim_cur; // 软限制
rlim_t rlim_max; // 硬限制
};
软限制是当前进程可以使用的资源限制,而硬限制是一个上限,进程只能借此提升软限制。
rlim_t是一个无符号整型。
linux中支持查询的资源限制如下:
- RLIMIT_AS 地址空间的最大大小。
- RLIMIT_CORE 生成的核心转储文件的最大大小。
- RLIMIT_CPU 进程可使用的最大 CPU 时间(秒)。
- RLIMIT_DATA 进程可使用的最大数据段大小。
- RLIMIT_FSIZE 进程可创建的最大文件大小。
- RLIMIT_MEMLOCK 可以锁定在内存中的最大字节数。
- RLIMIT_MSGQUEUE POSIX 消息队列的最大字节数。
- RLIMIT_nice 进程的最大“nice”值调整。
- RLIMIT_NOFILE 进程可以打开的最大文件描述符数。
- RLIMIT_NPROC 进程可创建的最大子进程数。
- RLIMIT_RSS 进程可用的最大常驻集大小。
- RLIMIT_SBSIZE 套接字缓冲区的最大大小。
- RLIMIT_STACK 进程的最大栈大小。
参考代码如下:
/**************************************************************************************
> File Name: rlimit.c
> Author: Conbiao
> Create Time: 2024.9.18 Wednesday
*************************************************************************************/
/**************************************************************************************
* HEADER
*************************************************************************************/
#include <stdio.h>
#include <sys/resource.h>
/**************************************************************************************
* MACRO
*************************************************************************************/
/**************************************************************************************
* FUNCTION DESCRIPTION
*************************************************************************************/
/**************************************************************************************
* MAIN
*************************************************************************************/
int main(int argc, char *argv[])
{
int ret = 0;
struct rlimit rl;
if(!getrlimit(RLIMIT_NICE,&rl))
{
printf("%s: current nice = %lu, the max nice = %lu \n",__func__,rl.rlim_cur,rl.rlim_max);
}
else
{
printf("%s: get nice failed!\n",__func__);
return -1;
}
if(!getrlimit(RLIMIT_CPU,&rl))
{
printf("%s: current cpu = %lu, the max cpu = %lu \n",__func__,rl.rlim_cur,rl.rlim_max);
}
else
{
printf("%s: get cpu failed!\n",__func__);
return -1;
}
if(!getrlimit(RLIMIT_NPROC,&rl))
{
printf("%s: current nproc = %lu, the max nproc = %lu \n",__func__,rl.rlim_cur,rl.rlim_max);
}
else
{
printf("%s: get nproc failed!\n",__func__);
return -1;
}
return ret;
}
运行结果如下图所示:
(2-1)
ps:资源限制影响到调用进程并由子进程集成。也就是说如果一个进程修改了其资源限制,那么其子进程也会集成这些修改后的限制。
三、setrlimit
setrlimit用于设置进程的资源限制。其函数原型如下:
头文件:#include <sys/resource.h>
函数原型: int setrlimit(int resource, const
struct rlimit *rlim); resource: 需要设置限制的资源类型。 rlim:指向 struct rlimit 结构体的指针
返回值: 返回0代表成功设置了资源限制,返回-1代表设置失败。
参考代码如下:
**/**************************************************************************************
> File Name: rlimit.c
> Author: Conbiao
> Create Time: 2024.9.18 Wednesday
*************************************************************************************/
/**************************************************************************************
* HEADER
*************************************************************************************/
#include <stdio.h>
#include <sys/resource.h>
/**************************************************************************************
* MACRO
*************************************************************************************/
/**************************************************************************************
* FUNCTION DESCRIPTION
*************************************************************************************/
/**************************************************************************************
* MAIN
*************************************************************************************/
int main(int argc, char *argv[])
{
int ret = 0;
struct rlimit rl;
if(!getrlimit(RLIMIT_NICE,&rl))
{
printf("%s: current nice = %lu, the max nice = %lu \n",__func__,rl.rlim_cur,rl.rlim_max);
}
else
{
printf("%s: get nice failed!\n",__func__);
return -1;
}
if(!getrlimit(RLIMIT_CPU,&rl))
{
printf("%s: current cpu = %lu, the max cpu = %lu \n",__func__,rl.rlim_cur,rl.rlim_max);
}
else
{
printf("%s: get cpu failed!\n",__func__);
return -1;
}
if(!getrlimit(RLIMIT_NPROC,&rl))
{
printf("%s: current nproc = %lu, the max nproc = %lu \n",__func__,rl.rlim_cur,rl.rlim_max);
}
else
{
printf("%s: get nproc failed!\n",__func__);
return -1;
}
if(!getrlimit(RLIMIT_NOFILE,&rl))
{
printf("%s: current nofile = %lu, the max nofile = %lu \n",__func__,rl.rlim_cur,rl.rlim_max);
}
else
{
printf("%s: get nofile failed!\n",__func__);
return -1;
}
rl.rlim_cur = 2048;
//rl.rlim_max = 1048577;
if(!setrlimit(RLIMIT_NOFILE,&rl))
{
printf("%s: set rlimit success!\n",__func__);
if(!getrlimit(RLIMIT_NOFILE,&rl))
{
printf("%s: new current nofile = %lu, the max nofile = %lu \n",__func__,rl.rlim_cur,rl.rlim_max);
}
else
{
printf("%s: get nofile failed!\n",__func__);
return -1;
}
}
else
{
return -1;
}
return ret;
}**
运行结果如下所示:
(3-1)
Ps: 一般只能修改软限制,硬限制需要root权限才能修改硬限制。