1

私は、デーモンを含む Python スレッドでいくつかの厄介なことをしています。

一部のテストで断続的なエラーが発生します。

Exception in thread myconsumerthread (most likely raised during interpreter shutdown):

スタック トレース/例外の詳細は提供されないことに注意してください。

自分のコードを精査しても効果はありませんでしたが、デバッグの次のステップについて少し迷っています。シャットダウン中にランタイムをダウンさせている可能性のある例外について詳しく知るために、どのようなデバッグ手法を使用できますか?

細字:

  • Windows、CPython、2.7.2 - Ubuntu では再現できません。
  • この問題は約 3% の確率で発生します。そのため、再現可能ですが、信頼性は高くありません。
  • myconsumerthread のコードには、すべてをキャッチする例外ハンドラがあり、例外の名前を に書き込もうとしますsys.stderr。(sysすでにシャットダウンされている可能性がありますか?)
  • この問題は、デーモン スレッドを非常に迅速にシャットダウンすることに関連していると思われます。それらが完全に初期化される前に。この分野の何かですが、証拠はほとんどありません.Pythonのバグを指摘するには確かに不十分です.
  • ハ、私は狂気への降下のターニングポイントを示す新しい症状を発見しました!
    • テスト ハーネス(ライブ コードではない) を使用し、それをimport timeまったく使用しない場合、頻度は約 0.5% に低下します。
    • テスト ハーネスを使用している場合import turtle(私のコードにはタートル グラフィックスはありません。すぐに見つけられる最も無関係なライブラリとしてこれを選択しました)、別のスレッドで例外がキャッチされ始め、次の場所で発生します。実行の約 3分の 1。
4

1 に答える 1

1

何度か同じエラーに遭遇しました。正確なメッセージを表示する例を見つけて生成しようとしています。

それまでは、私の記憶が正しければ、これらの領域に焦点を当てていました。

  • ポート、ファイル、キューなどを探しています...デーモンスレッドの外側で削除または閉じられました。
  • デーモン スレッドでブロッキング呼び出しを精査します。IE a Queue.get(block=True)pyserial.read()- timeout=Noneの場合

もう少し掘り下げた後、Queue's see comments hereに関連する同じタイプのエラーがポップアップ表示されます。

トレースバックが表示されないのは奇妙だと思います。catch-all except をコメントアウトして、Python にそれを std.error に送信させてみてください。願わくば、あなたが死にかけているものを見ることができるようになることを願っています。

以前にこの問題を見たことがあることを知っていた更新
... 以下に、そのエラーを生成する例を示します (実際には多くのエラーが発生します)。他にトレース バック メッセージも表示されないことに注意してqueue.getくださいtime.sleep。エラーはなくなるはずです。 これを再度実行しても、エラーは表示されません...これは、散発的な失敗率で見られたものと一致しています...エラーを表示するには、数回実行する必要がある場合があります。

私は通常、ブロック IO などのタイムアウト メソッドを提供しない場合、または使用するブロック呼び出しがない場合 (たとえば、ユーザー インターフェイスの更新) に time.sleep(x)スレッドを調整するために使用します。get()read()

そうは言っても、呼び出しを待っているときにスレッドがシャットダウンされるという問題があると思いtime.sleep()ます。sleep毎回この呼び出しが原因だと思いますが、メソッド内で実際に何が原因なのかはわかりません。私が知っている限りでは、これと同じ動作を示す他のブロッキング呼び出しがあります。

import time
import Queue
from threading import Thread

SLAVE_CNT = 50
OWNER_CNT = 10
MASTER_CNT = 2

class ThreadHungry(object):
    def __init__(self):
        self.rx_queue = Queue.Queue()

    def start(self):
        print "Adding Masters..."
        for x in range(MASTER_CNT):
            self.owners = []
            print "Starting slave owners..."
            for y in range(OWNER_CNT):
                owner = Thread(target=self.__owner_action)
                owner.daemon = True
                owner.start()
                self.owners.append(owner)

    def __owner_action(self):
        self.slaves = []
        print "\tStarting slaves..."
        for x in range(SLAVE_CNT):
            slave = Thread(target=self.__slave_action)
            slave.daemon = True
            slave.start()
            self.slaves.append(slave)

        while(1):
            time.sleep(1)
            #self.rx_queue.get(block=True)

    def __slave_action(self):
        while(1):
            time.sleep(1)
            #self.rx_queue.get(block=True)


if __name__ == "__main__":
    c = ThreadHungry()
    c.start()

    # Stop the threads abruptly after 5 seconds
    time.sleep(5)
于 2013-04-19T03:46:58.607 に答える