5

次のようなスレッドを実装する python プログラムがあります。

   class Mythread(threading.Thread):
        def __init__(self, name, q):
            threading.Thread.__init__(self)
            self.name = name
            self.q = q

        def run(self):
            print "Starting %s..." % (self.name)
            while True:
                ## Get data from queue
                data = self.q.get()
                ## do_some_processing with data ###
                process_data(data)
                ## Mark Queue item as done
                self.q.task_done()
            print "Exiting %s..." % (self.name)


    def call_threaded_program():
        ##Setup the threads. Define threads,queue,locks 
        threads = []    
        q = Queue.Queue()
        thread_count = n #some number
        data_list = [] #some data list containing data

        ##Create Threads
        for thread_id in range(1, thread_count+1):
            thread_name = "Thread-" + str(thread_id)
            thread = Mythread(thread_name,q)
            thread.daemon = True
            thread.start()

        ##Fill data in Queue
        for data_item in data_list:
            q.put(data_item)

        try:
            ##Wait for queue to be exhausted and then exit main program
            q.join()
        except (KeyboardInterrupt, SystemExit) as e:
            print "Interrupt Issued. Exiting Program with error state: %s"%(str(e))
            exit(1)

call_threaded_program() が別のプログラムから呼び出されています。

通常の状況でコードが機能しています。ただし、いずれかのスレッドでエラー/例外が発生した場合、プログラムは停止します (キューの結合が無限にブロックされるため)。このプログラムを終了できる唯一の方法は、端末自体を閉じることです。

スレッドが抜けたときにこのプログラムを終了させる最善の方法は何ですか? これを行うクリーンな(実際には私は何らかの方法を取る)方法はありますか?この質問が何度も出されていることは知っていますが、説得力のある答えを見つけることができません。助けていただければ幸いです。

編集:キューの結合を削除しようとしましたが、Python でスレッドを強制終了する方法はありますか? で 提案されているように、グローバル終了フラグを使用しました。 しかし、今の行動はとても奇妙で、何が起こっているのか理解できません。

    import threading
    import Queue
    import time

    exit_flag = False

    class Mythread (threading.Thread):
        def __init__(self,name,q):
            threading.Thread.__init__(self)
            self.name = name
            self.q = q

        def run(self):
            try:    
                # Start Thread
                print "Starting %s...."%(self.name)
                # Do Some Processing
                while not exit_flag:
                    data = self.q.get()
                    print "%s processing %s"%(self.name,str(data))
                    self.q.task_done()
                # Exit thread
                print "Exiting %s..."%(self.name)
            except Exception as e:
                print "Exiting %s due to Error: %s"%(self.name,str(e))


    def main():
        global exit_flag

        ##Setup the threads. Define threads,queue,locks 
        threads = []    
        q = Queue.Queue()
        thread_count = 20
        data_list = range(1,50)

        ##Create Threads
        for thread_id in range(1,thread_count+1):
            thread_name = "Thread-" + str(thread_id)
            thread = Mythread(thread_name,q)
            thread.daemon = True
            threads.append(thread)
            thread.start()

        ##Fill data in Queue
        for data_item in data_list:
          q.put(data_item)


        try:
          ##Wait for queue to be exhausted and then exit main program
          while not q.empty():
            pass

          # Stop the threads
          exit_flag = True

          # Wait for threads to finish
          print "Waiting for threads to finish..."
          while threading.activeCount() > 1:
            print "Active Threads:",threading.activeCount()
            time.sleep(1)
            pass

          print "Finished Successfully"
        except (KeyboardInterrupt, SystemExit) as e:
          print "Interrupt Issued. Exiting Program with error state: %s"%(str(e))


     if __name__ == '__main__':
         main()

プログラムの出力は次のとおりです。

    #Threads get started correctly
    #The output also is getting processed but then towards the end, All i see are
    Active Threads: 16
    Active Threads: 16
    Active Threads: 16...

その後、プログラムはハングするか、アクティブなスレッドの出力を続けます。ただし、終了フラグが True に設定されているため、スレッドの run メソッドは実行されていません。したがって、これらのスレッドがどのように維持されているか、または何が起こっているかについてはわかりません。

編集:問題が見つかりました。上記のコードでは、スレッドの get メソッドがブロックされていたため、終了できませんでした。代わりに、タイムアウト付きの get メソッドを使用するとうまくいきました。以下で変更した run メソッドだけのコードがあります

    def run(self):
            try:
                   #Start Thread
                   printing "Starting %s..."%(self.name)
                   #Do Some processing
                   while not exit_flag:
                          try:
                                data = self.q.get(True,self.timeout)
                                print "%s processing %s"%(self.name,str(data))
                                self.q.task_done()
                          except:
                                 print "Queue Empty or Timeout Occurred. Try Again for %s"%(self.name)


                    # Exit thread
                    print "Exiting %s..."%(self.name)
             except Exception as e:
                print "Exiting %s due to Error: %s"%(self.name,str(e))
4

2 に答える 2

0

私はCで一度やりました。基本的に、他のプロセスを開始し、それらを追跡するメインプロセスがありました。PID を保存し、戻りコードを待ちました。プロセスにエラーがある場合、コードはそれを示し、他のすべてのプロセスを停止できます。お役に立てれば

編集:

申し訳ありませんが、あなたがスレッドを使用していたことを私の回答で忘れていた可能性があります。でもまだまだ通用すると思います。スレッドをラップまたは変更して戻り値を取得するか、マルチスレッド プール ライブラリを使用できます。

Pythonでスレッドから戻り値を取得する方法は?

Python スレッド終了コード

于 2013-05-22T00:44:20.293 に答える