ホームページ >バックエンド開発 >Python チュートリアル >Python で Ctrl+C を使用してマルチスレッド プログラムを終了する問題を解決する

Python で Ctrl+C を使用してマルチスレッド プログラムを終了する問題を解決する

WBOY
WBOYオリジナル
2016-06-16 08:46:321887ブラウズ

复制代码代码如下:

#!/bin/env python
# -*-coding: utf- 8 -*-
#filename: peartest.py

インポート スレッド、シグナル

is_exit = False

def doStress(i, cc):
global is_exit
idx = i
ただし is_exit:
if (idx < 10000000):
print "thread[%d]: idx=%d"%(i, idx)
idx = idx + cc
else:
Break
print "thread[%d] complete."%i

def handler(signum, Frame):
global is_exit
is_exit = True
print "シグナル %d を受信, is_exit = %d"%(signum, is_exit)

if __name__ == "__main__":
signal.signal(signal.SIGINT) , handler)
signal.signal(signal.SIGTERM, handler)
cc = 5
for i in range(cc):
t = threading.Thread(target=doStress, args=(i ,cc))
t.start()

上は、サービスに直接リクエストを送信するのではなく、各オンライン プログラムごとに 1 個 (cc) ずつ送信され、その数が 1 つずつ印刷される模倣プログラムです。自分の仕事が完了すると、プロセスは正常に終了します。ただし、途中で退出する場合 (圧力測定プログラムを試していますが、途中で問題が発生したため、テストを停止する必要があります)、このタスクは ps で当然ながらプロセス番号を検出できます。上の例では、この信号を捕捉し、全体の値 is_exit を変更して、この値を検出して終了します。ただし、これは非常に頻繁です。

しかし、実際にはこのプログラムは機能せず、Ctrl+C を押している間はプログラムが通常どおり実行され、デーモンでない限り、明らかに Python のサブプログラムです。ただし、デーモンの後にメイン プロセスが終了し、次にプロセス全体がすぐに終了するように設計されているため、すべてのサブ プロセスが終了した後で自身が終了するまで、メイン プロセスで各サブ プロセスの状態を検出する必要もあります。したがって、上の例 29 行の後のコードは次のように変更できます:

复制代码代码如下:

threads=[]
for i in range(cc):
t = threading.Thread(target=doStress, args=(i, cc))
t.setDaemon(True)
thread.append(t)
t.start()
for i in range(cc):
thread[i].join()

もう一度試してみますが、このプロセスでは Ctrl+C も使用されていません。これは、join() 関数も同様に 1 つのネットワーク上で待機しており、メイン プロセスが信号を捕捉できないためです。 ()関数数判断線程が完了したかどうか:

复制代 代码如下:

while 1:
生きている = False
for i in range(cc ):
生きている = 生きているまたはスレッド[i].isAlive()
生きていない場合:
ブレーク

このように変更すると、プログラムは完全に計画どおりに実行されます。各オンライン プロセスで印刷されたすべての数字を印刷することも、途中で Ctrl + C を使用してプロセス全体を実行することもできます。

复制代码代码如下:

#!/bin/env python
# -*-coding: utf-8 -*-
#filename: peartest.py

インポート スレッド、シグナル

is_exit = False

def doStress(i, cc):
global is_exit
idx = i
while not is_exit:
if (idx < 10000000):
print "thread[%d]: idx=%d"%(i, idx)
idx = idx + cc
else:
Break
if is_exit:
print "受信終了シグナル、スレッド [%d] 停止。"%i
else:
print "スレッド [%d] 完了。"%i

def handler(signum, Frame):
global is_exit
is_exit = True
print "シグナル %d を受信, is_exit = %d"%(signum, is_exit)

if __name__ == "__main__":
シグナル.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
cc = 5
thread = []
for i in range(cc):
t = threading.Thread(target=doStress, args=(i,cc))
t.setDaemon(True)
thread.append(t)
t.start()
while 1:
生きている = False
for i in range(cc):
生きている = 生きている、またはスレッド[i].isAlive()
生きていない場合:
ブレーク

さらに、Python を使用してサービスを書き込む場合も、このようにする必要があります。有料サービスのオンライン プロセスは永続的に要求を受信して​​おり、退出することがないため、Ctrl+C キーを押してサービス全体を削除したい場合は、上に表示されます。圧力測定プログラムはプロセスの 1 つです。引き続き、Python マルチライン プロセス中に Ctrl+C の信号を入力してプロセス全体を停止する必要があります。

1. すべての子回線プロセスをデーモンに設定します。
2. isAlive() 関数を使用して、すべての子回線プロセスが完了するかどうかを判断します。主回線中に join() 関数などを使用して完了するのではありません。
3. Ctrl+C 信号の関数の 1 つにより、全体の局所変化が変更され、各子回線プロセスが検出可能になり、正常に終了します。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。