[Python-Dev] threads, SIGINT and time.sleep()

Mark Hammond mhammond@skippinet.com.au
Mon, 15 Jul 2002 18:37:05 +1000


Tim and I have been thrashing around in http://python.org/sf/581232 trying
to make time.sleep() interruptible for Windows.  This turns out to be quite
simple, but has unearthed some questions about thread interactions, and
seems to have changed semantics on Linux.

While I understand that the docs make almost no guarantees WRT threads and
signals, I am wondering what the "most desirable" semantics would be
assuming the platform supports it.

Consider a Python program with a main thread + 2 extra threads.  The 2 extra
threads are both in time.sleep().  When Ctrl+C is pressed, the docs seem to
clearly state that only the main thread should see a KeyboardInterrupt.  My
question is: what should happen to the time.sleep() threads?

It seems that Python 1.5.2 on Linux (as supplied by RedHat) would interrupt
the 2 threads with IOError(EINTR).  CVS Python currently seems to not
interrupt the threads at all, allowing the sleep() to continue the full
period.  (A time.sleep() in the main thread *is* interrupted in both
versions)

For Windows I can do either.  However, the Python 1.5.2 semantics seems to
make the most sense to me.  Was this change in behaviour post 1.5
intentional?  The code does not imply the new behaviour is intented (but the
code doesn't imply much at all!)

Test code and results below.  All clues welcomed!

Thanks,

Mark.

Test code:
----------
import time, threading

threads=[]
for i in range(2):
    t=threading.Thread(target=time.sleep, args=(30,))
    t.start()
    threads.append(t)
for t in threads:
    t.join()

Python 1.5.2 on Linux:
----------------------
Exception in thread Thread-1:
Traceback (innermost last):
...
  File "/usr/lib/python1.5/site-packages/threading.py", line 364, in run
    apply(self.__target, self.__args, self.__kwargs)
IOError: [Errno 4] Interrupted system call

Exception in thread Thread-2:
Traceback (innermost last):
...
  File "/usr/lib/python1.5/site-packages/threading.py", line 364, in run
    apply(self.__target, self.__args, self.__kwargs)
IOError: [Errno 4] Interrupted system call

Traceback (innermost last):
...
  File "/usr/lib/python1.5/threading.py", line 189, in wait
    waiter.acquire()
KeyboardInterrupt

Current CVS on Linux:
---------------------
[Pressing Ctrl+C has no effect - sleep() period expires, then...]
Traceback (most recent call last):
...
  File "/home/skip/src/python/dist/src/Lib/threading.py", line 190, in wait
    waiter.acquire()
KeyboardInterrupt