Note that there are some explanatory texts on larger screens.

plurals
  1. POSending arguments to Python threads blocks other threads
    text
    copied!<p>Consider this test application for passing arguments to Python threads:</p> <pre><code>#!/usr/bin/python3 from pprint import pprint import signal import sys import threading class CallThreads(threading.Thread): def __init__(self, target, *args): self._target = target threading.Thread.__init__(self) target(*args) def main(argv): phrases = ['hello', 'goodbye'] num = 0 for phrase in phrases: num += 1 thread_handler = CallThreads(someFunction, phrase, num) thread_handler.daemon = True thread_handler.start() return True def someFunction(a, b): print("Hi: "+str(a)+" and "+str(b)) return True def signal_handler(signal, frame): print(["Got SIGINT!"]) sys.exit(0) if __name__ == '__main__': signal.signal(signal.SIGINT, signal_handler) main(sys.argv) </code></pre> <p>In it's current state, it seems as though the <code>for phrase in phrases</code> loop is waiting for the thread to finish before starting another thread. That is, if <code>someFunction()</code> takes a long time to complete, then the then next thread will not start until the previous thread returns. Why is this, and how can I work around it while still sending arguments to the threads?</p> <p><strong>Edit:</strong> I've tried saving the <code>args</code> array in <code>self._args</code> in the constructor, and then calling <code>self._target(*self._args)</code> or <code>self._target(self._args)</code> in <code>def run (self):</code>. This actually works in Python 2, but not in Python 3. What should I do?</p> <p><strong>Edit:</strong> It seems that the problem is that in Python 3, the <code>run</code> method cannot access the private variables. That is, for the following improved code:</p> <pre><code>def __init__(self, target, *args): self._args = args threading.Thread.__init__(self) def run(self): someFunction(*self._args) </code></pre> <p>Note the following output:</p> <pre><code>Exception in thread Thread-1: Traceback (most recent call last): File "/usr/lib/python3.3/threading.py", line 639, in _bootstrap_inner self.run() File "./test.py", line 19, in run someFunction(*self._args) TypeError: someFunction() missing 2 required positional arguments: 'a' and 'b' </code></pre> <p>And adding a <code>pprint(self._args)</code> to the <code>run()</code> method indeed shows that the tuple returned is empty. However, changing the variables to non-private works! The following code runs fine:</p> <pre><code>def __init__(self, target, *args): self.target = target self.args = args threading.Thread.__init__(self) def run(self): self.target(*self.args) </code></pre> <p>Therefore, I can use the application with public variables in Python 3. <strong>However, is there any way to use private variables in the <code>CallThreads</code> class, as in Python 2?</strong></p> <p>Thanks!</p>
 

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