2017-02-12 2 views
0

Я пытаюсь создать подкласс threading.Thread, методы которого поточно. Я использую его для видео, но я подозреваю, что рабочий пример будет в целом полезен для людей.Расширяющий (stoppable) подклассы подкачки с потоковыми методами

Я понял здесь, что я никогда не создавал нить и никогда не вызывал метод start(), но я не знаю, где его назвать или как. Я также хочу сохранить ручку потока, чтобы я мог остановить ее, если получаю сигнал stop().

import threading 

class VideoThread(threading.Thread): 
    """Thread class with a stop() method. The thread itself checks 
    regularly for the stopped() condition.""" 

    def __init__(self, playlist=None): 
     super(VideoThread, self).__init__() 
     self._stop = threading.Event() 
     self._player_pgid_list = [] 
     if playlist: 
      self.start_sequence(playlist) 

    def stop(self): 
     self._stop.set() 

    def stopped(self): 
     return self._stop.isSet() 

    def start_sequence(self, playlist): 
     if not isinstance(playlist, list): 
      raise ValueError("Expecting a list") 
     for video in playlist: 
      if not self.stopped(): 
       self.__start_video__(video) 

    def __start_video__(self, video): 
     if not isinstance(video, dict): 
      raise ValueError("Expecting a dictionary of video data") 
     # start the video 
     # store the video pgid so we can kill it if we have to 
     # tight wait loop to check for stopped condition 
     # kill all video(s) if necessary using the stored pgids 

Класс работает, насколько это идет, но, конечно, ни один из методов не на самом деле резьбой.

start_sequence() является общедоступным, чтобы я мог начать резьбовую последовательность видео, как это:

video = VideoThread() 
video.start_sequence([films[1], films[3], films[2]]) 

Или когда я создаю экземпляр класса, как это:

video = VideoThread([films[1], films[3], films[2]]) 

Позже, если мне нужно, чтобы остановить его , Я могу:

video.stop() 

Что мне не хватает?

ответ

1

Вы должны переименовать метод start_sequence в run и удалите параметр playlist (используйте self.playlist вместо). Кроме того, удалите эти две последние строки в методе __init__. Я имею в виду:

class VideoThread(threading.Thread): 


    def __init__(self, playlist=None): 
     super().__init__() 
     self._stop = threading.Event() 
     self._player_pgid_list = [] 
     self.playlist = playlist 

    def run(self): 
     if not isinstance(self.playlist, list): 
      raise ValueError("Expecting a list") 
     for video in self.playlist: 
      if not self.stopped(): 
       self.__start_video__(video) 

    ... 

Затем, чтобы использовать класс просто сделать:

playlist = VideoThread(films) 
playlist.start() 

И вы можете остановить его с помощью:

playlist.stop() 

Обратите внимание, что при вызове .start, он вызывает run в отдельном потоке управления, проверьте official documentation для получения дополнительной информации.

+0

Используя этот метод, я могу связать '' start() '', как в '' VideoThread (films) .start() ''? –

+0

Да, вы можете, но если вы это сделаете, вы потеряете ссылку на поток, а это значит, что вы не сможете остановить его позже. Лично я этого не делал. –

Смежные вопросы