Search code examples
pythonmultithreadingtwistedtwisted.internet

Looping call in twisted.internet.reactor?


I'm trying to looping call a function in thread.
This is my code:

from twisted.internet import reactor
from twisted.internet.task import LoopingCall

def func_that_cost_many_time():
    ...

looping_call = LoopingCall(func_that_cost_many_time)
reactor.callInThread(looping_call.start, 60)
reactor.run()
...

It seem that LoopingCall is running in another thread and code below line 9 are able to run.
But once I press Ctrl-C, I always get Received SIGINT, shutting down. but the application stills running. Is something wrong with my code or there is a better solution?

My question is: After Ctrl-C, the func_that_cost_many_time task won't stop.


Solution

  • You cannot start a LoopingCall in a non-reactor thread. In general, there are almost no Twisted APIs you can use in a non-reactor thread. The ones you can do this with are clearly and explicitly marked.

    Since you used a Twisted API in an unsafe way, you got some arbitrary behavior that arises from the details of just how the implementation is broken when used like this.

    Instead, what you should do is start the LoopingCall normally and make the function it is driving non-blocking, perhaps by calling reactor.callInThread (or maybe better yet, deferToThread) inside of it to call some other thread-safe API.