2016-07-18 10 views
0

メインオブジェクトで開始された後に独立して実行されるデーモンスレッドを作成しました。私はそれがスタックを介して実行したい様々な機能をプッシュすることができます。しかし、デーモンスレッドがスタック内に2つ以上の関数(ビルドしているプロジェクトの設計選択肢)を持つことは決してありません。したがって、run_this_functionというメソッドがこのスレッドで実行されていて、メインオブジェクトがその関数を再びスタックにプッシュすると、run_this_functionの途中で停止して、スレッドにプッシュされた新しい関数を再起動します。実行中の途中で一連のステートメントを停止する

私の質問は、一連のステートメントが開始された後にそれらを停止する方法があるかどうかです。

import threading 
import time 


class myThread(object): 
    """ 
    The run() method will be started and it will run in the background 
    until the application exits. 
    """ 

    def __init__(self, interval=1): 
     self.interval = interval 
     self.thread_stack = [] 
     thread = threading.Thread(target=self.run, args=()) 
     thread.daemon = True        
     thread.start()        

    def run(self): 
     # Method that runs forever 
     lock = threading.Lock() 
     while True: 
      if self.thread_stack: 
       lock.acquire() 
       try: 
        # if a method is already running on this thread, end it. 
        new_function = thread_stack.pop() 
       finally: 
        lock.release() 
       # run new function 
      else: 
       time.sleep(self.interval) 

    def some_function(self): 
     #do something 
     #do something 
     #do something else 
     #do one more thing 

上記のコードはこれまでに書いたものです。 myThreadオブジェクトを作成し、thread_stackに実行したいメソッドをプッシュします。だからもし私がすでに実行している関数(some_function)があったら、最初の2つの実行ステートメントの後のように途中で中止することができます。すべての行についてif文を用意する必要がありますか?

また、私のスレッディングの使用方法についてもコメントしてください。私はまだそれに非常に新しいです。ありがとう!をスレッドを使用して作成さ

スレッドを殺すか、中断することは困難である::)

答えて

0

Pythonは2つのスレッドのAPIがあります。スレッドが定期的__trace方法 再定義

  • (別のスレッドからの)スレッドで例外を上げる停止条件
  • をチェック有する

    さらに、this github gistと、 のコメントを別のスレッドに送信する別の方法を見てください。

    これらの方法にはすべて欠点があり、特定の状況では機能しない可能性があります。 特に、threadingで作成されたスレッドは、システムコール中の場合は中断することができません。 マルチプロセッシングライブラリを使用して作成

    スレッドは、しかし、本当の プロセスであり、Unixシグナルを受け取ることができるかterminate方法で殺されます。 欠点は、異なるアドレス空間 で実行され、信号を処理するときにリソース が適切にクリーンアップされるように注意する必要があることです。

    ここでは、マルチプロセッシングでこれを行う方法のコード例を示します。 プログラムを実行した後に遅延を入力して(3のように)、キューに という新しいジョブを追加します。キューがサイズ2を超えると、現在のジョブは になります。すべてのジョブが終了するのを待つために0の遅延を入力してください。

    #!/usr/bin/env python 
    
    from multiprocessing import Process 
    import Queue 
    import os 
    import signal 
    import threading 
    import time 
    
    class RunJobs(): 
        def __init__(self): 
        self.queue = Queue.Queue() 
        self.current_process = None 
        pass 
    
        def run_loop(self): 
        # intended to be run in 
        while True: 
         # atomically get the next job 
         job = self.queue.get(True, None) 
         if job is None: 
         break 
         p = Process(target=run_job, args=job) 
         self.current_process = p 
         p.start() 
         p.join() 
         self.current_process = None 
    
        def abort(self): # abort the current process 
        p = self.current_process 
        if p: 
         p.terminate() 
         # alternatively, use os.kill(p.pid, ...) to send a signal 
    
        def add_job(self, job): 
        # atomically add the job calling self.abort() 
        # if there are too many jobs on the queue 
        # N.B.: For illustrative purposes only. There is 
        # a race condition here. To avoid it use locks. 
        self.queue.put(job) 
        if self.queue.qsize() > 2: self.abort() 
    
    def run_job(delay, message): 
        for i in xrange(5): 
        print "\n ===", message, "i =", i 
        time.sleep(delay) 
    
    def main(): 
        rj = RunJobs() 
        t = threading.Thread(target=rj.run_loop) 
        t.start() 
    
        i = 1 
        while True: 
        delay = raw_input("Enter delay for job {}: ".format(i)) 
        delay = int(delay) 
        if delay == 0: 
         rj.add_job(None) 
         break 
        job = (delay, "job {} - delaying for {}".format(i, delay)) 
        rj.add_job(job) 
        i += 1 
        print "Waiting for all jobs to finish..." 
        t.join() 
    
    if __name__ == '__main__': 
        main() 
    
  • +0

    ご了承ください。実際にマルチプロセッシングの説明に役立ちますが、実際には(真のループ中に)停止しないスレッドを実装し、グローバルスタック(thread_stack)を実行する関数を追加していました。スレッドを閉じずにこれらの関数を終了する方法を知りたかったのです。しかし、私はすでにそれを考え出しました。 Thansk !! –

    +0

    もしあなたがそれを理解したら、答えとして投稿してください。 – ErikR

    関連する問題