【发布时间】:2021-03-04 05:25:28
【问题描述】:
在创建不同的基准时,我经常以最佳延迟为目标。众所周知,访问堆中的内存比访问堆栈中的内存要昂贵得多。我们现在是 2021 年,当我尝试 ulimit -s 时,我发现我有 8192kbs 可用。不能再高一点吗?
我想知道如何使用c代码设置它,发现setrlimit和getrlimit:
getrlimit() 和 setrlimit() 系统调用分别获取和设置资源限制。每个资源都有一个相关的软限制和硬限制,由 rlimit 结构定义 [...]
我找到了this answer 和this one,虽然它们都很有趣,但还是有一些我不明白的地方:
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/resource.h>
#include <errno.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
int main(int argc, char *argv[])
{
struct rlimit old, new;
struct rlimit *newp;
pid_t pid;
if (!(argc == 2 || argc == 4)) {
fprintf(stderr, "Usage: %s <pid> [<new-soft-limit> "
"<new-hard-limit>]\n", argv[0]);
exit(EXIT_FAILURE);
}
pid = atoi(argv[1]); /* PID of target process */
newp = NULL;
if (argc == 4) {
new.rlim_cur = atoi(argv[2]);
new.rlim_max = atoi(argv[3]);
// newp = &new; // I comment this line to avoid messing up with the processes too much;)
}
/* Set CPU time limit of target process; retrieve and display previous limit */
if (prlimit(pid, RLIMIT_CPU, newp, &old) == -1)
errExit("prlimit-1");
;
printf("Previous limits: soft=%lld; hard=%lld\n", (long long) old.rlim_cur, (long long) old.rlim_max);
/* Retrieve and display new CPU time limit */
if (prlimit(pid, RLIMIT_CPU, NULL, &old) == -1)
errExit("prlimit-2");
printf("New limits: soft=%lld; hard=%lld\n", (long long) old.rlim_cur, (long long) old.rlim_max);
//perror("error:");
exit(EXIT_FAILURE);
}
如果我尝试任何进程,我会看到,至少在 Ubuntu 18.04 和使用 gcc 编译时,当它尝试检索当前和最大限制时,它将返回 -1。 这个 -1 返回值究竟是什么?是“设置为默认系统值”还是“检索失败”,如果是“检索失败”,是什么原因?为什么if (prlimit(pid, RLIMIT_CPU, newp, &old) == -1)没有触发?
Previous limits: soft=-1; hard=-1
但是,如果我取消注释newp = &new;(故意注释),那么我可以为该过程设置一个新值,包括当前值和最大值,这没有问题,这非常了不起。 理论上我可以设置的最大值是多少?我尝试使用sudo gcc raise_stack.c && ./a.out 9194 8192 16384,但我不敢自己尝试烧毁我的 CPU ;)
New limits: soft=8192; hard=16384
非常感谢您帮助我更好地理解 getrlimit。
注意:避免“如果您必须提高堆栈内存,那么您做错了什么”。这不是意见问题。
编辑:无法确定在哪里设置 errno 以获得正确的结果
error:: Success
error:: Success
error:: Success
error:: Success
error:: Success
error:: Success
Previous limits: soft=-1; hard=-1
error:: Success
New limits: soft=-1; hard=-1
error:: Success
我设置后
long long a = prlimit(pid, RLIMIT_CPU, newp, &old);
perror("error:");
但仍然不是我正在寻找的 ERRNO。
【问题讨论】:
-
这个-1返回值到底是什么。阅读manual。在 Linux 中,常见的做法是成功返回 0,错误返回非零。然后将
errno设置为指示更精确的错误代码。出错时,调用perror以获取errno值的字符串描述。 -
这是我所做的(正如你所看到的评论),我得到了
error: success,所以我真的不明白 -
能否提供准确的输入输出?
-
@kaylum 感谢您抽出宝贵时间提供帮助!查看我的编辑
-
//perror("error:");我不明白你为什么在那个地方打电话给perror。此时没有要检查的错误。perror必须在函数失败后立即调用。在这种情况下,printf是最后一次调用,它可能将errno设置为成功。