posix_ipc
posix_ipc copied to clipboard
message queue raise exception when receives a signal
Hi there,
When I use a signal inside my program, the posix_ipc.MessageQueue object raises a posix_ipc.SignalError
exception; I believe this is different from what we normally expect, example program to show this problem:
import os
import signal
import posix_ipc
def receive_handler(signal, stack):
print(f"Received signal: {signal}")
q = posix_ipc.MessageQueue("/test", flags=posix_ipc.O_CREAT)
signal.signal(signal.SIGUSR1, receive_handler)
print(f'Runing (PID: {os.getpid()}) ...')
q.receive()
After running this program, if you send a signal with another process, let's say with kill
command:
kill -s USR1 5426
You get:
Running (PID: 5426) ...
Received signal: 10
Traceback (most recent call last):
File "/home/bahram/.virtualenvs/tmp-1237b73b1e1465c/main.py", line 16, in <module>
q.receive()
posix_ipc.SignalError: The wait was interrupted by a signal
Comparing this to other queues like queue.Queue
they catch the signal and after doing the sigaction continue their functionality.
Hi @GreatBahram, I'm very sorry for letting this issue sit for so long. I don't think I realized you had opened it.
I didn't know about this behavior of queue.Queue
when I wrote this code. It didn't even occur to me to try to make posix_ipc.MessageQueue
behave like queue.Queue
. In any case, posix_ipc.MessageQueue
has behaved this way for 13 years now and I wouldn't want to break anyone's code that relies on this behavior.
In addition, it would be difficult to mimic the queue.Queue
behavior. When the user calls mq.receive()
with a timeout, the posix_ipc code calls the C function mq_timedreceive()
. If a signal occurs, that call ends, and errno
is set to EINTR
. If I wanted to mimic queue.Queue
's behavior, it sounds like I'd have to call mq_timedreceive()
again, but I wouldn't know how long the first call had waited so the timing would be wrong.
To summarize, I thank you for the interesting suggestion, but I'm not going to make this change.