Updated: April 19, 2023 |
Set and get the limit on a system resource
#include <sys/resource.h> int prlimit( pid_t pid, int resource, const struct rlimit * new_rlp, struct rlimit * old_rlp ); int prlimit64( pid_t pid, int resource, const struct rlimit64 * new_rlp, struct rlimit64 * old_rlp );
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
The prlimit() and prlimit64() functions can be used to set and get limits on the consumption of a variety of system resources by a process and each process it creates. They combine and extend the functionality of setrlimit() and getrlimit(). The prlimit64() function is a large-file support version of prlimit().
The possible resources, their descriptions, and the actions taken when the current limit is exceeded are summarized below (the _NP in some names stands for non-POSIX):
Resource | Classification | Description | Action |
---|---|---|---|
RLIMIT_AS | POSIX | The maximum size, in bytes, of a process's mapped address space. | If the limit is exceeded, mmap() fails with errno set to ENOMEM. In addition, the automatic stack growth fails with the effects outlined above. |
RLIMIT_CORE | POSIX | The maximum size, in bytes, of a core file that a process may create. A limit of 0 prevents the creation of a core file. | The writing of a core file terminates at this size. |
RLIMIT_CPU | POSIX | The maximum amount of CPU time, in seconds, that a process may use. This is a soft limit only. | If the limit is exceeded, SIGXCPU is sent to the process. If the process is ignoring SIGXCPU, SIGKILL is sent to the process. |
RLIMIT_DATA | POSIX | The maximum size, in bytes, that a process's heap may be. In QNX Neutrino, RLIMIT_DATA covers all mappings made by the process that are MAP_ANON | MAP_PRIVATE that aren't MAP_STACK, which corresponds typically to heap allocations. | If the limit is exceeded, mmap() fails with errno set to ENOMEM. |
RLIMIT_FREEMEM | Unix | The limit on total memory usage, in tenths of a per cent of the total system memory. For example, a limit of 500 on a system with 1000 MB of memory would be 500 MB. | This limit is shared with all other processes;
a memory allocation by this process fails if it would cause the total system memory usage
of all processes to exceed this process's limit.
The intention is to allow the memory pool to be crudely partitioned. For example, important system processes could be given an RLIMIT_FREEMEM value of RLIM_INFINITY, and all others a value of 800. That would partition memory into an 80% chunk that's shared by everybody and a 20% chunk that's shared by important system processes. |
RLIMIT_NOCONN_NP | QNX Neutrino | The maximum number of connections a process can create,
including file descriptors and side-channel connections.
Most processes are created with three fds (stdin, stdout,
and stderr)
and a connection to the system process.
RLIMIT_NOCONN_NP should be greater than or equal to RLIMIT_NOFILE; it's up to you to set these limits so that they don't conflict. |
ConnectAttach() gives an error of EMFILE |
RLIMIT_NOFILE | POSIX | One more than the maximum value that the system may assign to a newly created descriptor. This limit constrains the number of file descriptors that a process may create. | Functions that allocate a file descriptor give an error of EMFILE |
RLIMIT_NPROC | Unix | The maximum number of processes. | Attempts to create new processes fail. |
RLIMIT_NTHR | Unix | The maximum number of threads. | Attempts to create threads (e.g., by calling pthread_create()) fail. |
RLIMIT_OFILE | Unix | Same as RLIMIT_NOFILE. | |
RLIMIT_RSS | Unix | The maximum resident set size for a process; the same as RLIMIT_AS. | Same as RLIMIT_AS. |
RLIMIT_SIGEVENT_NP | QNX Neutrino | The maximum number of sigevents that a process can have registered at a given time. | MsgRegisterEvent() gives an error of EAGAIN. |
RLIMIT_STACK | POSIX | The maximum size, in bytes, that a process's stack may be. The system will not
automatically grow the stack beyond this limit. Within a process, prlimit() increases the limit on the size of your stack, but doesn't move current memory segments to allow for that growth. To guarantee that the process stack can grow to the limit, the limit must be altered prior to the execution of the process in which the new stack size is to be used. Within a multithreaded process, prlimit() has no impact on the stack size limit for the calling thread if the calling thread isn't the main thread. A call to prlimit() for RLIMIT_STACK impacts only the main thread's stack, and should be made only from the main thread, if at all. |
The SIGSEGV signal is sent to the process. If the process is holding or ignoring SIGSEGV, or is catching SIGSEGV and hasn't made arrangements to use an alternate stack, the disposition of SIGSEGV is set to SIG_DFL before it's sent. |
RLIMIT_TIMERS_NP | QNX Neutrino | The maximum number of timers that a process can create. | Attempts to create timers by calling timer_create() or TimerCreate() fail with an error of EAGAIN. Note that this limit doesn't apply to TimerTimeout() |
RLIMIT_VMEM | Unix | Same as RLIMIT_AS. | Same as RLIMIT_AS. |
Because limit information is stored in the per-process information, the shell builtin ulimit command (see the entry for ksh in the Utilities Reference) must directly execute this system call if it's to affect all future processes created by the shell.
The values of the current limit of the following resources affect these parameters:
Resource | Parameter |
---|---|
RLIMIT_NOFILE | OPEN_MAX |
The result of setting a limit to RLIM_SAVED_MAX or RLIM_SAVED_CUR is unspecified unless a previous call to prlimit() returned that value as the soft or hard limit for the corresponding resource limit.
A limit whose value is greater than RLIM_INFINITY is permitted.
struct rlimit old; struct rlimit new; pid_t pid; int ret; pid = ... // Get the old limit for RLIMIT_CPU ret = prlimit(pid, RLIMIT_CPU, NULL, &old); if (ret != 0) { perror("prlimit"); return errno; } printf("old: cur=%lu, max=%lu \n", old.rlim_cur, old.rlim_max); new.rlim_cur = ... new.rlim_max = ... printf("new: cur=%lu, max=%lu \n", new.rlim_cur, new.rlim_max); // Get and set the limit for RLIMIT_CPU ret = prlimit(pid, RLIMIT_CPU, &new, &old); if (ret != 0) { perror("prlimit"); return errno; } printf("old: cur=%lu, max=%lu \n", old.rlim_cur, old.rlim_max);
prlimit64() is Large-file support
Safety: | |
---|---|
Cancellation point | No |
Interrupt handler | No |
Signal handler | Yes |
Thread | Yes |