Pythonのsys.exitと自分自身のリロードについて
解決済
回答 4
投稿
- 評価
- クリップ 0
- VIEW 2,038
Pythonでとある条件が一致したらsys.exit()を実行して自分自身を終了させたいのですが、何故か終了されずに処理が実行され続けます。
理由として、threadingモジュールを用いて別スレッドでWebSocket接続をし、受信したデーターの処理を行っているからというのが考えられます。
この場合、threadingモジュールにより生成されたスレッドを停止させれば解決するような気がするのですが、このページを参考にしてみても、
AttributeError: 'Thread' object has no attribute 'exit'
と表示され停止できません。更に公式のドキュメントを見てみると、現状停止はできないと記載されていました。
何とかしてsys.exit()で終了する方法はないでしょうか。
また、sys.exit()の他にも自分自身をリロードする方法も取りたいのですが、調べてみたところこんなページがありまして、早速載っていたコードを真似てみたのですが、
TypeError: execv() arg 2 must be a tuple or list
というエラーが返ってきます。このエラーを調べてみたのですがヒットしませんでした。引数には何を指定すればよいのでしょうか。
以上2点回答していただけると幸いです。
よろしくお願いいたします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+2
やってやれないことはありません。
import sys
import time
import threading
def target():
i = 0
while True:
print("/-\\|"[i%4]+"\r", end="")
time.sleep(1)
i += 1
def main():
# th = threading.Thread(target=target) # これだと終了しない
th = threading.Thread(target=target, daemon=True) # こっちにするとsys.exit()で終了する
th.start()
time.sleep(5)
sys.exit()
if __name__ == "__main__":
main()
ミソはdaemon=True
で、公式ドキュメントにも説明があります(ちなみに、今回はpython2のドキュメントにも同じ記載があるようですが、本当はpython3を使っているならpython3のドキュメントを確認した方が良いです)。
スレッドには "デーモンスレッド (daemon thread)" であるというフラグを立てられます。 このフラグには、残っているスレッドがデーモンスレッドだけになった時に Python プログラム全体を終了させるという意味があります。フラグの初期値はスレッドを生成したスレッドから継承します。フラグの値は daemon プロパティまたは daemon コンストラクタ引数を通して設定できます。
注釈 デーモンスレッドは終了時にいきなり停止されます。デーモンスレッドで使われたリソース (開いているファイル、データベースのトランザクションなど) は適切に解放されないかもしれません。きちんと (gracefully) スレッドを停止したい場合は、スレッドを非デーモンスレッドにして、Event のような適切なシグナル送信機構を使用してください。
17.1. threading — スレッドベースの並列処理 — Python 3.6.5 ドキュメント
まあ、書いてある通り、これは強制的に終了させられるので、問題になるようなら(リソースに対してなにかやるなら)自分で制御してやる必要があります。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
from os import _exit as os_exit
#os_exit() # 色々無視してとにかく終了
# あとはこの辺を参照
from ctypes import pythonapi
pythonapi.PyThreadState_SetAsyncExc
from os import kill
from signal import pthread_kill
# ちなみにWindows限定ですがこんな殺し方もあります。
https://github.com/sakurai-youhei/T800.winthread/blob/master/T800/winthread.py
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
スレッドは、自分自身で終了するように考えないといけません。
たとえば、終了用のフラグかなんかを設けて、スレッド中で定期的にこれを参照し、これが立っていれば終了する、とか。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
自分自身のリロードについて
DANIWEBより
python = sys.executable
os.execl(python, python, * sys.argv)
これで自分自身のリロード(再起動)ができます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 89.97%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2018/06/12 22:44
回答ありがとうございました。