2017-12-07 22 views
1

私はIPアドレスをpingするクラスを作成しようとしており、接続された時間と接続されていない時間のレコードを保持しています。Python、スレッドを停止

このクラスはGUIの一部であるため、ユーザーからの問い合わせに応じてこのスレッドを停止します。

いくつか見つかったQ &この問題を解決するには、どちらも実際にスレッドを停止させるものではありません。

私は方法、ここに私のPingerクラスだself.run()

を停止します。このクラスの一部にしようとしています:

class Pinger(threading.Thread): 
    def __init__(self, address='', rate=1): 
     threading.Thread.__init__(self) 

     self.address = address 
     self.ping_rate = rate 
     self.ping_vector, self.last_ping = [], -1 
     self.start_time, self.last_status = datetime.datetime.now(), [] 
     self.timestamp, self.time_vector = 0, [datetime.timedelta(0)] * 4 

    def run(self): 
      self.start_ping() 

    def start_ping(self): 
     self.timestamp = datetime.datetime.now() 
     while True: 
      ping_result = os.system('ping %s -n 1 >Null' % self.address) 
      self.ping_vector.append(ping_result) 

      if self.last_ping != ping_result: 
       text = ['Reachable', 'Lost'] 
       print(str(self.timestamp)[:-4], self.address, text[ping_result]) 

      round_time_qouta = datetime.datetime.now() - self.timestamp 
      self.timestamp = datetime.datetime.now() 
      self.update_time_counter(ping_result, round_time_qouta) 

      self.last_ping = ping_result 
      time.sleep(self.ping_rate) 

    def update_time_counter(self, ping_result=0, time_quota=datetime.timedelta(0)): 
     """self.time_vector = [[cons.succ ping time],[cons.not_succ ping time], 
     [max accum succ ping time],[max accum not_succ ping time] """ 

     p_vec = [0, 1] 

     self.time_vector[p_vec[ping_result]] += time_quota 
     if self.time_vector[p_vec[ping_result]].total_seconds() > self.time_vector[ 
      p_vec[ping_result] + 2].total_seconds(): 
      self.time_vector[p_vec[ping_result] + 2] = self.time_vector[p_vec[ping_result]] 

     self.time_vector[p_vec[ping_result - 1]] = datetime.timedelta(0) 

     self.last_status = [ping_result, self.chop_milisecond(self.time_vector[ping_result]), 
          self.chop_milisecond(self.time_vector[ping_result + 2]), 
          self.chop_milisecond(datetime.datetime.now() - self.start_time)] 

     print(str(self.timestamp)[:-4], "State: " + ['Received', 'Lost'][ping_result], 
       " Duration: " + self.last_status[1], " Max Duration: " + self.last_status[2], 
       "Total time: " + self.last_status[3]) 

    def chop_milisecond(self, time): 
     return str(time).split('.')[0] 
+1

あなたを通知するために使用[ 'threading.Event'](https://docs.python.org/2/library/threading.html#event-objectsが)ですイベントが設定されている場合はスレッドを定期的にチェックし、イベントが設定されている場合は終了します。 – zwer

+1

@zwerコードで説明できますか? –

答えて

1

私が言っていた通り私のコメントでは、最も簡単な方法は、終了時にスレッドに信号を送るのにthreading.Eventを使用することです。こうすることで、イベントを公開して、他のスレッドがスレッド内から状態を確認して要求を出して終了できるようにすることができます。 pinger_instance.kill.set()を、あなたが行われている:ちょうどそれを呼び、いつでも好きなときに、スレッドが(あなたのUIからのように)停止

class Pinger(threading.Thread): 

    def __init__(self, address='', rate=1): 
     threading.Thread.__init__(self) 
     self.kill = threading.Event() 
     # the rest of your setup... 

    # etc. 

    def start_ping(self): 
     self.timestamp = datetime.datetime.now() 
     while not self.kill.is_set(): 
      # do your pinging stuff 

    # etc. 

:あなたのケースでは

は、のような単純なものでした。ブロック os.system()が呼び出され、 time.sleep()のためにあなたが Pinger.start_ping()メソッドの終了時にそれが殺されるのに時間がかかることを覚えておいてください。

0

使用_Thread_stop():

MyPinger._Thread__stopを()

1

デーモンとして実行するために、あなたのクラスを少し違うようにコーディングします。

休暇start_pingコードアウトとは、次のコードを使用します。

MyPinger = threading.Thread(target = self.start_ping, name="Pinger") 
MyPinger.setDaemon(True) 
MyPinger.start() # launch start_ping 

をし、それを停止する_Thread_stopを()を使用することができ、それは...少しのブルートです:

if MyPinger.IsAlive(): 
    MyPinger._Thread__stop() 
1

@zwerがリードしてくれてありがとうございます。 ここに私の完全なコード(変更がマークされている)

class Pinger(threading.Thread): 
    def __init__(self, address='', rate=1): 
     threading.Thread.__init__(self) 

     self.address = address 
     self.ping_rate = rate 
     self.ping_vector, self.last_ping = [], -1 
     self.start_time, self.last_status = datetime.datetime.now(), [] 
     self.timestamp, self.time_vector = 0, [datetime.timedelta(0)] * 4 
     self.event = threading.Event() # <---- Added 

    def run(self): 
     while not self.event.is_set(): # <---- Added 
      self.start_ping() 
      self.event.wait(self.ping_rate) # <---- Added (Time to repeat moved in here) 

    def stop(self):  # <---- Added (ease of use) 
     self.event.set() # <---- Added (set to False and causes to stop) 


    def start_ping(self): 
     self.timestamp = datetime.datetime.now() 
     # While loop ##--- > Deleted. now it loops in run method ##### 
     ping_result = os.system('ping %s -n 1 >Null' % self.address) 
     self.ping_vector.append(ping_result) 

     if self.last_ping != ping_result: 
      text = ['Reachable', 'Lost'] 
      print(str(self.timestamp)[:-4], self.address, text[ping_result]) 

     round_time_qouta = datetime.datetime.now() - self.timestamp 
     self.timestamp = datetime.datetime.now() 
     self.update_time_counter(ping_result, round_time_qouta) 

     self.last_ping = ping_result 
     #### time.sleep (self.ping_rate) # <---- deleted 

    def update_time_counter(self, ping_result=0, time_quota=datetime.timedelta(0)): 
     """self.time_vector = [[cons.succ ping time],[cons.not_succ ping time], 
     [max accum succ ping time],[max accum not_succ ping time] """ 

     p_vec = [0, 1] 

     self.time_vector[p_vec[ping_result]] += time_quota 
     if self.time_vector[p_vec[ping_result]].total_seconds() > self.time_vector[ 
      p_vec[ping_result] + 2].total_seconds(): 
      self.time_vector[p_vec[ping_result] + 2] = self.time_vector[p_vec[ping_result]] 

     self.time_vector[p_vec[ping_result - 1]] = datetime.timedelta(0) 

     self.last_status = [ping_result, self.chop_milisecond(self.time_vector[ping_result]), 
          self.chop_milisecond(self.time_vector[ping_result + 2]), 
          self.chop_milisecond(datetime.datetime.now() - self.start_time)] 

     print(str(self.timestamp)[:-4], "State: " + ['Received', 'Lost'][ping_result], 
       " Duration: " + self.last_status[1], " Max Duration: " + self.last_status[2], 
       "Total time: " + self.last_status[3]) 

    def chop_milisecond(self, time): 
     return str(time).split('.')[0] 

    def get_status(self): 
     return self.last_status 


c = Pinger('127.0.0.1', 5) 
c.start() 
time.sleep(10) 
c.stop() 
関連する問題