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呼び出してみました。これは実際には Python 2 では機能しますが、Python 3 では機能しません。どうすればよいですか?self._target(*self._args)self._target(self._args)def run (self):

編集: 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)そして、メソッドに a を追加すると、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 でパブリック変数を使用してアプリケーションを使用できます。ただし、 Python 2 のように、クラスでプライベート変数を使用する方法はありますか?CallThreads

ありがとう!

4

1 に答える 1

4

target(args)問題は、 のコンストラクターを呼び出すことですCallThreads

したがって、次の呼び出しCallThreads.__init__()は、終了するまでブロックします。

thread_handler = CallThreads(someFunction, phrase, num)

更新: 1 つの可能性は次のとおりです。

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 に答える