Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you're already using Twisted, you should never need to "wait" like this.</p> <p>As you've described it:</p> <blockquote> <p>I spawn a thread to run a long operation ... This long operation also spawns some threads using twisted's deferToThread ...</p> </blockquote> <p>That implies that you're calling <code>deferToThread</code> from your "long operation" thread, not from your main thread (the one where <code>reactor.run()</code> is running). As Jean-Paul Calderone already noted in a comment, you can <em>only</em> call Twisted APIs (such as <code>deferToThread</code>) from the main reactor thread.</p> <p>The lock-up that you're seeing is a common symptom of not following this rule. It has nothing to do with the GIL, and everything to do with the fact that you have put Twisted's reactor into a broken state.</p> <p>Based on your loose description of your program, I've tried to write a sample program that does what you're talking about based entirely on Twisted APIs, spawning all threads via Twisted and controlling them all from the main reactor thread.</p> <pre><code>import time from twisted.internet import reactor from twisted.internet.defer import gatherResults from twisted.internet.threads import deferToThread, blockingCallFromThread def workReallyHard(): "'Work' function, invoked in a thread." time.sleep(0.2) def longOperation(): for x in range(10): workReallyHard() blockingCallFromThread(reactor, startShortOperation, x) result = blockingCallFromThread(reactor, gatherResults, shortOperations) return 'hooray', result def shortOperation(value): workReallyHard() return value * 100 shortOperations = [] def startShortOperation(value): def done(result): print 'Short operation complete!', result return result shortOperations.append( deferToThread(shortOperation, value).addCallback(done)) d = deferToThread(longOperation) def allDone(result): print 'Long operation complete!', result reactor.stop() d.addCallback(allDone) reactor.run() </code></pre> <p>Note that at the point in <code>allDone</code> where the reactor is stopped, you could fire off another "long operation" and have it start the process all over again.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload