Why is there a error "Cannot Allocate Memory" while creating message queue in POSIX?
Adrian's answer is correct, but since this is a frustratingly common error to run into on Linux when first attempting to use POSIX message queues for anything non-trivial, I thought I'd add some helpful particulars.
First, to understand the RLIMIT_MSGQUEUE
resource limit, see the formula at man setrlimit
:
RLIMIT_MSGQUEUE (Since Linux 2.6.8) Specifies the limit on the number of bytes that can be allocated for POSIX message queues for the real user ID of the calling process. This limit is enforced for mq_open(3). Each message queue that the user creates counts (until it is removed) against this limit according to the formula:
bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) +
attr.mq_maxmsg * attr.mq_msgsize
where attr is the mq_attr structure specified as the fourth argument to mq_open(3). The first addend in the formula, which includes sizeof(struct msg_msg *) (4 bytes on Linux/i386), ensures that the user cannot create an unlimited number of zero-length messages (such messages nevertheless each consume some system memory for bookkeeping overhead).
Given the default MQ settings (mq_maxmsg
= 10, mq_msgsize
= 8192) on Linux, the above formula works out to only about 10 message queues for the default limit of 819200 bytes. Hence why you will run into this problem as soon as you e.g. forget to close and unlink a couple of queues once done with them.
To raise the RLIMIT_MSGQUEUE
resource limit to the maximum allowed for the user, you can use something like the following in your application's startup code:
#ifdef __linux__
// Attempt to raise the resource limits for POSIX message queues to
// the current hard limit enforced for the current real user ID:
struct rlimit rlim = {RLIM_INFINITY, RLIM_INFINITY};
const int rc = getrlimit(RLIMIT_MSGQUEUE, &rlim);
if (rc == 0 && rlim.rlim_cur != rlim.rlim_max) {
rlim.rlim_cur = rlim.rlim_max;
setrlimit(RLIMIT_MSGQUEUE, &rlim);
}
#endif
If you also ensure that you set the mq_maxmsg
and mq_msgsize
attributes to lower values when opening a queue (see man mq_open
), you may be able to get away with a couple of hundred queues even within the constraints of the default RLIMIT_MSGQUEUE
hard limit. Depending on your particular use case, of course.
Adjusting the RLIMIT_MSGQUEUE
hard limit is not difficult if you have root access to the system. Once you've figured out what the limit ought to be, adjust the system-wide settings in /etc/security/limits.conf
. For example, to set a hard and soft limit of 4 megabytes for the www-data
user group, and no limitation for the superuser, you'd add the following lines to the file:
@www-data - msgqueue 4194304
root - msgqueue unlimited
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With