Any workarounds for Python's select and handling of EINTR in Linux?

1k views Asked by At

In one of my recent projects I happened to have in the same process (a Python program, its a multithreaded application):

  • a Boost::Python module to a library that linked against the AVT PvAPI SDK, i.e. in the widest sense a driver to get image frames from a camera. This library (the PvApi SDK) produces a SIGALRM internally every some milliseconds.

  • another plain Python module that was intended to do some serial I/O using pyserial. This in turn uses Python's wrapper select.select to POSIX select. Which turned out to be interrupted (errno == EINTR) everytime the signal is produced by the other module.

  • the same issue could be observed on any call of Python's time.sleep, resp. the POSIX sleep, that is used internally.

These issues are apparantly not present in Windows, as sleep and select will not be interrupted by any signal there (according to the documentation). And these issues are not much of a problem in C/C++, as you can (and should, though) restart the calls if they have been interrupted.

However, as the Python implementation (source code/Modules/selectmodule.c) doesn't handle this case (EINTR), am I forced to implement my own C/C++ serial driver and sleep function to use in Python? Or to move away from Python for this project? As Python makes programming so much easier I'm very interested if anyone has had similar problems and found a nice workaround or simple fix for this. Right now I don't have the capacity to work out the necessary fixes for the Python modules myself. Or maybe I have missed some other option?

Any ideas?

2

There are 2 answers

0
moooeeeep On BEST ANSWER

In the meantime a PEP was published to address this issue (PEP 475).

As it looks, the behavior was fixed since Python 3.5 in 2015.

1
Adam Rosenfield On

Try using signal.sigintterupt to make the SIGALRM signal restart system calls automatically. Or you could use signal.signal(signal.SIGALRM, signal.SIG_IGN) to ignore the alarm signal, assuming you're not using it for anything.