考虑这个测试应用程序将参数传递给Python线程:
#!/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)
在它的当前状态下,似乎for phrase in phrases
循环在启动另一个线程之前等待线程完成。也就是说,如果someFunction()
需要很长时间才能完成,那么下一个线程将不会启动,直到前一个线程返回。为什么会这样,以及如何在仍然向线程发送参数的同时解决它?
修改
我尝试在args
中将self._args
数组保存在构造函数中,然后在self._target(*self._args)
中调用self._target(self._args)
或def run (self):
。这实际上适用于Python 2,但不适用于Python 3.我该怎么办?
修改
似乎问题是在Python 3中,run
方法无法访问私有变量。也就是说,对于以下改进的代码:
def __init__(self, target, *args):
self._args = args
threading.Thread.__init__(self)
def run(self):
someFunction(*self._args)
请注意以下输出:
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'
向pprint(self._args)
方法添加run()
确实表明返回的元组为空。但是,将变量更改为非私有作品!以下代码运行正常:
def __init__(self, target, *args):
self.target = target
self.args = args
threading.Thread.__init__(self)
def run(self):
self.target(*self.args)
因此,我可以在Python 3中使用带有公共变量的应用程序。但是,有没有办法在CallThreads
类中使用私有变量,就像在Python 2中一样?
谢谢!
答案 0 :(得分:4)
问题是您在target(args)
的构造函数上调用CallThreads
。
因此,以下调用会阻止CallThreads.__init__()
完成:
thread_handler = CallThreads(someFunction, phrase, num)
<强>更新强> 一种可能性如下:
class CallThreads(threading.Thread):
def __init__(self, *args):
self._args = args
threading.Thread.__init__(self)
def run(self):
someFunction(*self._args)