Dustin Oprea
Dustin Oprea

Reputation: 10276

CTRL+C doesn't interrupt call to shared-library using CTYPES in Python

When calling a loop being performed in a C shared-library (dynamic library), Python will not receive a KeyboardInterrupt, and nothing will respond (or handle) CTRL+C.

What do I do?

Upvotes: 10

Views: 2072

Answers (3)

Askold Ilvento
Askold Ilvento

Reputation: 1520

I used a threaded solution but then switched to a signal one. The work-around I use is to send SIGTERM from SIGINT handler, e.g.:

signal.signal(signal.SIGINT, lambda s, f : os.kill(os.getpid(), signal.SIGTERM))

Here I just want to save a core idea of the solution to find it faster next time and the reason why I have changed the approach. The threaded variant does not suite for me because OpenMP becomes significantly slower when it is called not from the main thread.

Upvotes: 1

jfs
jfs

Reputation: 414905

Unless you use PyDLL or PYFUNCTYPE; the GIL is released during the ctypes calls. Therefore the Python interpreter should handle SIGINT by raising KeyboardInterrupt in the main thread if the C code doesn't install its own signal handler.

To allow the Python code to run in the main thread; you could put the ctypes call into a background thread:

import threading

t = threading.Thread(target=ctypes_call, args=[arg1, arg2, ...])
t.daemon = True
t.start()
while t.is_alive(): # wait for the thread to exit
    t.join(.1)

Upvotes: 4

Dustin Oprea
Dustin Oprea

Reputation: 10276

You will have to declare a signal handler for SIGINT, within the C, which is, hopefully, your project.

Upvotes: 1

Related Questions