What is RLIMIT_SIGPENDING?
RLIMIT_SIGPENDING is a Linux-specific limit (since kernel 2.6.8) that sets the maximum number of signals that may be queued for the real user ID of the calling process. It primarily affects sigqueue() — which can send a signal with an associated data value and can queue multiple instances. When the limit is exceeded, sigqueue() fails with EAGAIN.
What Counts Against the Limit
The count of queued signals includes both realtime and standard signals. This is worth noting because standard signals (SIGTERM, SIGUSR1, etc.) can only be queued once to a process — a second SIGTERM while one is pending does not increase the count. Realtime signals (SIGRTMIN to SIGRTMAX) can be queued multiple times.
sigqueue(). Even if the queue is full, kill() can still deliver one instance of each standard signal (or one realtime signal) that is not already pending. This ensures basic signal delivery is never completely blocked by the queue limit.Default Value and Per-User-ID Scope
The initial default was 1024 (kernel 2.6.8). Since kernel 2.6.12, the default was changed to equal the RLIMIT_NPROC default (proportional to available memory). Like RLIMIT_NPROC, the scope is the real user ID: the limit counts queued signals across all processes owned by that user.
The limit is only checked in the process that set it (or inherited it). A process that never set RLIMIT_SIGPENDING (has RLIM_INFINITY) is not constrained.
Checking the Queue: /proc/PID/status SigQ
Since kernel 2.6.12, the /proc/PID/status file contains a SigQ field that shows the current queue depth and limit:
$ grep SigQ /proc/self/status
SigQ: 0/3569
# Format: current_queued / max_allowed
# current_queued = signals currently pending for this user
# max_allowed = RLIMIT_SIGPENDING soft limit
Code Example — sigqueue() and RLIMIT_SIGPENDING
#include
#include
#include
#include
#include <sys/resource.h>
int main(void)
{
struct rlimit rl;
union sigval sv;
int sent = 0;
pid_t self = getpid();
/* Block SIGRTMIN so signals queue up rather than being delivered */
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGRTMIN);
sigprocmask(SIG_BLOCK, &mask, NULL);
/* Set a small RLIMIT_SIGPENDING */
rl.rlim_cur = 5;
rl.rlim_max = 5;
setrlimit(RLIMIT_SIGPENDING, &rl);
printf("RLIMIT_SIGPENDING set to 5\n");
/* Send SIGRTMIN to ourselves via sigqueue() until limit is hit */
sv.sival_int = 0;
while (1) {
if (sigqueue(self, SIGRTMIN, sv) == -1) {
if (errno == EAGAIN) {
printf("sigqueue() EAGAIN after %d signals: limit hit\n", sent);
break;
}
perror("sigqueue"); break;
}
sent++;
sv.sival_int = sent;
printf(" Queued signal %d\n", sent);
}
/* kill() can still deliver even though queue is full */
if (kill(self, SIGRTMIN) == 0)
printf("kill() still works even with full queue\n");
return 0;
}
/* Compile: gcc -o sigpending_demo sigpending_demo.c */
Interview Questions
sigqueue() is affected. When the queue is full, sigqueue() returns -1 with errno set to EAGAIN (Resource temporarily unavailable).
No. RLIMIT_SIGPENDING only applies to sigqueue(). Even when the queue is at the limit, kill() can still send one instance of each signal that is not already pending. This prevents basic signal delivery from being permanently blocked.
Read /proc/PID/status and look for the SigQ field (available since kernel 2.6.12). It shows “current/max” — for example “3/3569” means 3 signals are currently queued and the limit is 3569.
Yes. The count includes both realtime signals (which can be queued multiple times) and standard signals (which can only be queued once per process). Standard signals queued a second time are silently dropped but do not cause sigqueue() to fail unless the total count across both types exceeds the limit.
