次のコードがあります
def signal_handler(self,signum,frame):
self.kill_received = True
print "signal received",signum
self.condition.set()
def mainFunc(self):
while not self.kill_received:
* do something *
実際のシグナルが発生すると、signal_handler が signum を出力しますが、ループは続きます。ループ内で self.kill_received 値を出力してみました。シグナルハンドラの実行後でも、false を示していました。
また、シグナル ハンドラ内に self.kill_received の出力を入れると、True になっていることがわかります。でも外には映りません。シグナルハンドラから関数を呼び出しても、変更された kill_received の値が反映されます。メインプロセスとシグナルハンドラー用に2つの並列アドレス空間または何かがあるかのようです(私はPythonが初めてで、その内部の仕組みが不明であるため、わかりません)
誰かが Python でのインスタンス変数のこの動作を説明できますか? 「global kill_received」を使用してみましたが、「未定義」エラーが発生します..
リクエストに応じてコード全体を以下に示します
class CreateData(multiprocessing.Process):
def __init__(self, recv_queue, reportName, reportDirectory, condition, chunkSize = 100, maxReportSize = 350, isChunked = True):
multiprocessing.Process.__init__(self)
self.reportName = reportName
self.reportDirectory = reportDirectory
self.recv_queue = recv_queue
self.chunkSize = chunkSize * 1024 * 1024
self.maxReportSize = maxReportSize * 1024 * 1024
self.current_chunk_size = 0
self.isChunked = isChunked
self.chunk_suffix = 0
# Flow control attributes
signal.signal(signal.SIGTERM,self.signal_handler)
signal.signal(signal.SIGUSR1,self.signal_handler)
self.kill_received = False
self.condition = condition
def signal_handler(self,signum,frame):
self.kill_received = True
print "signal received",signum
self.condition.set()
def run(self):
self.makeReport(True)
def makeReport(self,isChunked):
swing=20*(self.chunkSize/100)
up_swing=(self.chunkSize+swing) #upper swing size
low_swing=(self.chunkSize-swing) #lower swing size
while(not self.kill_received):
#{
self.funcTest()
#}
編集 この問題は、シグナルがこのクラス内の関数から開始された場合にのみ発生します。メイン プロセスから os.kill(child_pid,signal) を実行すると、期待どおりに処理されます。
しかし、このクラスの関数から os.kill(os.ppid(),signal) を実行すると、シグナル ハンドラ内での出力のみが行われます。変数が設定されていません。