1

考虑这个将参数传递给 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)or self._target(self._args)in 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)在方法中添加 arun()确实表明返回的元组是空的。但是,将变量更改为非私有有效!以下代码运行良好:

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 中一样?

谢谢!

4

1 回答 1

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)
于 2013-06-14T15:05:42.897 回答