prlimit64 函数
1. 函数介绍
prlimit64
用于获取和设置进程的资源限制。它是 getrlimit
和 setrlimit
的增强版本,支持64位资源限制值。
2. 函数原型
#define _GNU_SOURCE
#include <sys/resource.h>
int prlimit64(pid_t pid, int resource, const struct rlimit64 *new_limit, struct rlimit64 *old_limit);
3. 功能
获取和/或设置指定进程的资源限制。可以用于控制进程使用的各种系统资源,如内存、文件描述符、CPU时间等。
4. 参数
- pid_t pid: 目标进程ID(0表示当前进程)
- int resource: 资源类型(如RLIMIT_AS, RLIMIT_NOFILE等)
- *const struct rlimit64 new_limit: 新的资源限制(NULL表示不设置)
- *struct rlimit64 old_limit: 保存旧的资源限制(NULL表示不获取)
5. 返回值
- 成功: 返回0
- 失败: 返回-1,并设置errno
6. 相似函数,或关联函数
- getrlimit/setrlimit: 32位版本
- ulimit: shell内置命令
- getrusage: 获取资源使用情况
7. 示例代码
#define _GNU_SOURCE
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
/**
* 显示资源限制信息
*/
void display_resource_limit(int resource, const char *name) {
struct rlimit64 limit;
if (prlimit64(0, resource, NULL, &limit) == 0) {
printf("%-20s: ", name);
if (limit.rlim_cur == RLIM64_INFINITY) {
printf("无限制");
} else {
printf("软限制=%lld", (long long)limit.rlim_cur);
}
if (limit.rlim_max == RLIM64_INFINITY) {
printf(", 硬限制=无限制\n");
} else {
printf(", 硬限制=%lld\n", (long long)limit.rlim_max);
}
} else {
printf("%-20s: 获取失败 (%s)\n", name, strerror(errno));
}
}
/**
* 演示prlimit64获取资源限制
*/
int demo_prlimit64_get() {
printf("=== prlimit64 获取资源限制示例 ===\n");
// 显示常见的资源限制
display_resource_limit(RLIMIT_AS, "虚拟内存");
display_resource_limit(RLIMIT_CORE, "核心文件大小");
display_resource_limit(RLIMIT_CPU, "CPU时间");
display_resource_limit(RLIMIT_DATA, "数据段大小");
display_resource_limit(RLIMIT_FSIZE, "文件大小");
display_resource_limit(RLIMIT_NOFILE, "文件描述符数");
display_resource_limit(RLIMIT_NPROC, "进程数");
display_resource_limit(RLIMIT_STACK, "栈大小");
return 0;
}
/**
* 演示prlimit64设置资源限制
*/
int demo_prlimit64_set() {
struct rlimit64 old_limit, new_limit;
int result;
printf("\n=== prlimit64 设置资源限制示例 ===\n");
// 获取当前文件描述符限制
if (prlimit64(0, RLIMIT_NOFILE, NULL, &old_limit) == 0) {
printf("当前文件描述符限制: 软限制=%lld, 硬限制=%lld\n",
(long long)old_limit.rlim_cur, (long long)old_limit.rlim_max);
}
// 尝试设置新的文件描述符限制
new_limit.rlim_cur = 1024; // 软限制
new_limit.rlim_max = 2048; // 硬限制
result = prlimit64(0, RLIMIT_NOFILE, &new_limit, NULL);
if (result == 0) {
printf("成功设置新的文件描述符限制\n");
// 验证设置结果
if (prlimit64(0, RLIMIT_NOFILE, NULL, &old_limit) == 0) {
printf("设置后文件描述符限制: 软限制=%lld, 硬限制=%lld\n",
(long long)old_limit.rlim_cur, (long long)old_limit.rlim_max);
}
} else {
printf("设置文件描述符限制失败: %s\n", strerror(errno));
printf("注意:可能需要root权限或在硬限制范围内调整\n");
}
// 演示内存限制设置
printf("\n尝试设置虚拟内存限制:\n");
new_limit.rlim_cur = 100 * 1024 * 1024; // 100MB
new_limit.rlim_max = 200 * 1024 * 1024; // 200MB
result = prlimit64(0, RLIMIT_AS, &new_limit, NULL);
if (result == 0) {
printf("成功设置虚拟内存限制为100MB\n");
} else {
printf("设置虚拟内存限制失败: %s\n", strerror(errno));
}
return 0;
}
/**
* 演示资源限制的实际影响
*/
int demo_resource_limit_effect() {
struct rlimit64 limit;
int fd_array[100];
int i, fd_count = 0;
printf("\n=== 资源限制实际影响演示 ===\n");
// 获取当前文件描述符限制
if (prlimit64(0, RLIMIT_NOFILE, NULL, &limit) == 0) {
printf("当前文件描述符软限制: %lld\n", (long long)limit.rlim_cur);
}
// 尝试打开大量文件来测试限制
printf("尝试打开文件...\n");
for (i = 0; i < 100; i++) {
char filename[32];
snprintf(filename, sizeof(filename), "test_file_%d.txt", i);
int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd == -1) {
printf("在打开第 %d 个文件时失败: %s\n", i, strerror(errno));
printf("当前已打开 %d 个文件\n", fd_count);
break;
}
fd_array[fd_count++] = fd;
if (i % 20 == 0) {
printf("已成功打开 %d 个文件\n", fd_count);
}
}
// 关闭所有打开的文件
for (i = 0; i < fd_count; i++) {
close(fd_array[i]);
char filename[32];
snprintf(filename, sizeof(filename), "test_file_%d.txt", i);
unlink(filename);
}
printf("清理完成\n");
return 0;
}
int main() {
if (demo_prlimit64_get() == 0) {
demo_prlimit64_set();
demo_resource_limit_effect();
printf("\n=== prlimit64 使用总结 ===\n");
printf("用途:控制进程资源使用,防止资源耗尽\n");
printf("注意:某些限制需要特权权限才能修改\n");
printf("常见资源类型:内存、文件描述符、CPU时间、进程数等\n");
}
return 0;
}
总结
文件I/O函数特点:
资源管理函数:
1. prlimit64: 现代化的资源限制管理,支持64位值