2

以下は私のテストコードです。
python2.7 で実行すると、生成されたすべてのスレッドが終了するまでプログラムがシグナルを受信しないことが示されます。
一方、python3.2 では、メイン スレッドの sigintHandler のみが呼び出されます。
Python がスレッドとシグナルを処理する方法に混乱しています。スレッドを生成し、そのスレッド内でシグナル処理を行うにはどうすればよいですか? それはまったく可能ですか?

from __future__ import print_function
from threading import Thread
import signal, os, sys
from time import sleep

def sigintHandler(signo, _):
    print("signal %d caught"%signo)

def fn():
    print("thread sleeping")
    sleep(10)
    print("thread awakes")

signal.signal(signal.SIGINT, sigintHandler)

ls = []
for i in range(5):
    t = Thread(target=fn)
    ls.append(t)
    t.start()

print("All threads up, pid=%d"%os.getpid())
for i in ls:
    i.join()

while True:
    sleep(20)
4

2 に答える 2

0

Python はシグナルを非同期的に処理しません。Python にシグナル ハンドラーをインストールすると、ランタイムはフラグを設定するだけの C シグナル ハンドラー スタブをインストールします。インタープリターは、バイトコード命令間のフラグをチェックしてから、python シグナル ハンドラーを呼び出します。つまり、シグナル ハンドラーはバイトコード操作の間でのみ実行できます。メインの Python スレッドが C コードを実行している場合、現在の操作が完了するまでシグナルを処理できません。SIGINT (つまり、control-C) がブロックされた IO を中止するための規定がありますが、メイン スレッドでのみです。

つまり、シグナルの受信に基づいてスレッドでコードを実行する場合は、メイン スレッドでシグナルを受信し、キューを介してワーカー スレッドにメッセージを送信します。割り込み不可の呼び出しでメイン スレッドがブロックされないようにする必要があります。Python 2.7 では、join は相互接続可能ではありません (ご存じのとおり)。それ以降のバージョンの python ではそうです。

于 2013-11-07T19:38:19.830 に答える
0

あなたは言った:python3.2では、メインスレッドのsigintHandlerだけが呼び出されます。

正しいと思います。ここから:シグナルとスレッド

Python シグナル ハンドラは、シグナルが別のスレッドで受信された場合でも、常にメインの Python スレッドで実行されます。これは、スレッド間通信の手段としてシグナルを使用できないことを意味します。代わりに、threading モジュールの同期プリミティブを使用できます。

また、新しいシグナル ハンドラを設定できるのはメイン スレッドだけです。

于 2013-10-31T07:39:12.657 に答える