デーモンスレッドの説明


237

ではPythonドキュメント 、それは言います:

スレッドは「デーモンスレッド」としてフラグを立てることができます。このフラグの重要性は、デーモンスレッドだけが残されると、Pythonプログラム全体が終了することです。初期値は作成スレッドから継承されます。

誰かがそれが何を意味するのかを明確に説明したり、スレッドをdaemonicどこに設定するかを示す実際的な例を持っていますか?

明確にしてください。つまり、スレッドをdaemonicに設定しない唯一の状況は、メインスレッドが終了した後もスレッドを実行し続けたい場合です。

回答:


447

一部のスレッドは、キープアライブパケットの送信、定期的なガベージコレクションの実行など、バックグラウンドタスクを実行します。これらは、メインプログラムが実行されている場合にのみ役立ちます。デーモン以外のスレッドが終了したら、これらを強制終了しても問題ありません。

デーモンスレッドがなければ、プログラムを完全に終了する前に、それらを追跡し、終了するように指示する必要があります。それらをデーモンスレッドとして設定することで、それらを実行させて忘れさせることができ、プログラムが終了すると、デーモンスレッドは自動的に強制終了されます。


1
したがって、非デーモンに設定されているファイル書き込み操作を実行している子スレッドがある場合、それは明示的に終了させる必要があるということですか?
Ciasto piekarz 14年

8
@san書き込みが終了した後、ライタースレッドは何をしますか?戻るだけですか?その場合は、それで十分です。デーモンスレッドは通常、ループで実行され、それ自体では終了しないもの用です。
Chris Jester-Young

それは何もせず、どちらも戻りません、ファイル書き込み操作を実行する唯一の目的
Ciasto piekarz 14年

2
@sanスレッド関数の底から落ちると、暗黙的に戻ります。
Chris Jester-Young

Noneその場合に戻りますが、問題ではなく、戻り値は使用されません。
Chris Jester-Young

30

ある種のダッシュボードウィジェットを作成しているとしましょう。この一環として、メールボックスに未読メッセージ数を表示します。したがって、次のような小さなスレッドを作成します。

  1. メールサーバーに接続し、未読メッセージの数を尋ねます。
  2. 更新されたカウントでGUIに通知します。
  3. しばらく寝ます。

ウィジェットが起動すると、このスレッドが作成され、デーモンが指定され、起動されます。これはデーモンなので、考える必要はありません。ウィジェットが終了すると、スレッドは自動的に停止します。


18

他のポスターには、デーモンスレッドを使用する状況の例がいくつかありました。しかし、私の推奨は、それらを使用することは決してありません。

それはそれらが役に立たないからではなく、それらを使用した場合に経験することができるいくつかの悪い副作用があるからです。デーモンスレッドは、Pythonランタイムがメインスレッドの内容を分解し始めた後も実行でき、かなり奇妙な例外を引き起こします。

詳細はこちら:

https://joeshaw.org/python-daemon-threads-considered-harmful/

https://mail.python.org/pipermail/python-list/2005-February/343697.html

厳密に言うと、それらを必要とすることはなく、場合によっては実装が簡単になるだけです。


まだpython 3のこの問題?ドキュメントには、これらの「奇妙な例外」に関する明確な情報はありません。
kheraud '19

5
Joeのブログ投稿:「2015年6月更新:これはPythonバグ1856です。Python3.2.1および3.3で修正されましたが、修正は2.xにバックポートされませんでした。(2.7ブランチにバックポートしようとすると、別のバグが発生しましたデーモンスレッドはPython> = 3.2.1では問題ないかもしれませんが、以前のバージョンでは間違いなくありません。」
2016

ここで私の経験を共有したいと思います:Threadとして複数回生成された関数がありました。その中に、Pythonのインスタンスがloggingあり、スレッドの終了後、すべてのオブジェクト(各スレッド/関数のファイル記述子)が破棄されることを期待していました。プログラムの最後に、などの多くの出力が表示されました IOError: [Errno 24] Too many open files:。でlsof -p pid_of_program、スレッド/関数が仕事を終えたタフでさえ、FDが開いていることを発見しました。回避策は?関数の最後でログハンドラーを削除します。したがって、daemonicスレッドは信頼できない...
ivanleoncz

17

それについて考えるためのより簡単な方法、おそらく:メインが戻ったときに、デーモン以外のスレッドがまだ実行されている場合、プロセスは終了しません。

少しアドバイス:スレッドと同期が関係している場合、クリーンシャットダウンは簡単に失敗します。回避できる場合は、そうしてください。可能な限りデーモンスレッドを使用してください。


13

Chrisはすでにデーモンスレッドとは何かを説明しているので、実際の使用法について話しましょう。多くのスレッドプールの実装では、タスクワーカーにデーモンスレッドを使用します。ワーカーは、タスクキューからタスクを実行するスレッドです。

新しいタスクがいつ表示されるかわからないため、ワーカーはタスクキュー内のタスクを無期限に待機し続ける必要があります。タスクを割り当てるスレッド(メインスレッドなど)は、タスクがいつ終了したかを知るだけです。メインスレッドはタスクキューで空になるのを待って終了します。ワーカーがユーザースレッド、つまりデーモン以外の場合、プログラムは終了しません。ワーカーは何も役に立たないにもかかわらず、これらの無期限に実行されているワーカーを待ち続けます。マークワーカーデーモンスレッド。メインスレッドは、タスクの処理が完了するとすぐに、それらを強制終了します。


4
気をつけて!プログラムが重要なタスク(「バックグラウンドで」ファイルを更新するなど)をデーモンタスクキューに送信する場合、タスクを実行する前にプログラムが終了する可能性があります。
ソロモンスロー

10

クリスの引用:「...プログラムが終了すると、デーモンスレッドは自動的に強制終了されます。」まとめると思います。メインプログラムの実行が完了すると突然終了するので、使用するときには注意が必要です。


4

2番目のスレッドが非デーモンの場合、その終了基準が非デーモンスレッドの出口にも関連付けられているため、アプリケーションのプライマリメインスレッドは終了できません。Pythonではスレッドを強制的に強制終了できないため、アプリはデーモン以外のスレッドが終了するまで実際に待機する必要があります。この動作が適切でない場合は、2番目のスレッドをデーモンとして設定して、アプリケーションが終了しないようにします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.