Вопрос о разработке потоков Python (Работа с методом, который блокирует навсегда) - PullRequest
0 голосов
/ 15 февраля 2011

ОБНОВЛЕННАЯ ПОЧТА Итак, я нашел решение для того, что я делал, это использовать Есть ли способ убить поток в Python?

Я бы хотел получить подтверждение по дизайну. У нас довольно большая система, и одним из компонентов системы является коммуникационный компонент. Он отвечает за две вещи: одну отправку сообщений и две очереди любых полученных сообщений (в файл, базу данных, очередь и т. Д.). Я получаю сообщение через предоставленную библиотеку, которая в основном может просто ждать вечно сообщение прибыть.

Вопросы:

1) Лучше ли иметь один основной поток и два вспомогательных потока?

2) Лучше ли разрешить потоку приема просто блокироваться навсегда, пока не прибудет сообщение? Или я должен разрешить тайм-аут (что является исключением) и просто продолжать цикл?

Дайте мне знать, какая дополнительная информация вам может понадобиться.

Прямо сейчас у меня в основном есть поток приема и основной поток (который также обрабатывает отправку), который вы можете увидеть ниже. Единственное, что не включено ниже, это то, что теперь я могу назвать «завершить» в MessageReceiver, и он завершится.


ОРИГИНАЛЬНЫЙ ПОЧТА Я пытаюсь обернуть поток вокруг некоторой логики получения в Python. По сути, у нас есть приложение, которое будет иметь поток в фоновом опросе для сообщений, проблема, с которой я столкнулся, заключается в том, что часть, которая на самом деле тянет сообщения, всегда ждет сообщения. Делая невозможным завершение ... В итоге я завернул тягу в другой поток, но я хотел убедиться, что лучшего способа сделать это не было.

Оригинальный код:

class Manager:
   def __init__(self):
        receiver = MessageReceiver()
        receiver.start()
        #do other stuff sending/etc...

class MessageReceiver(Thread):
   receiver = Receiver()

   def __init__(self):
        Thread.__init__(self)


   def run(self):           
       #stop is a flag that i use to stop the thread...
       while(not stopped ):
          #can never stop because pull below blocks
          message  = receiver.pull()
          print "Message" + message   

Я знаю, что существуют очевидные проблемы с блокировкой, но является ли это подходящим способом управления потоком получения, который всегда ожидает сообщения?

Одна вещь, которую я заметил, это то, что она потребляет 100% ресурсов процессора в ожидании сообщения ... ** Если вам нужно увидеть логику остановки, пожалуйста, дайте мне знать, и я опубликую.

Ответы [ 3 ]

0 голосов
/ 15 февраля 2011

1) Если ваш третий поток просто будет ожидать на получателе и отправителе, в этом нет необходимости.

Работа с несколькими процессами менее удобна, чем с несколькими потоками.Большим преимуществом процессов является то, что они избегают ограничений CPython в отношении потоков, то есть два потока не могут выполнять обработку одновременно (но один поток может работать, в то время как другие блокируют IO).Таким образом, если оба потока не выполняют большую обработку, вам лучше оставить их в одном и том же процессе.

2) Вы должны разрешить своему получателю тайм-аут и проверить наличие флага завершения в цикле.

0 голосов
/ 05 марта 2011

Поскольку реального ответа на этот вопрос не было, я подведу итог:

  1. Один главный поток, который обрабатывает отправку и порождает принимающий поток
  2. Блокировать навсегда, исключения являютсядорогостоящий, поэтому нет необходимости давать ему время ожидания.

Чтобы остановить поток, я в основном устанавливаю флаг остановки, а затем прекращаю базовое соединение в сообщении «завершить» родителя.Взамен, что вызывает у ребенка исключение.

В блоке обработки исключений я затем проверяю ConnectionException, если был установлен флаг "stop", я грациозно останавливаю принимающий поток, если это был неблагодарный выход, я уведомлю родительский поток.

Надеюсь, это поможет, это было очень раздражающей проблемой, но я рад, что это закончилось.

class Manager:
   def __init__(self):
      self.receiver = MessageReceiver(shutdown_hook = self.shutdown_hook)
      self.receiver.start()
      #do other stuff sending/etc...
   def terminate(self):
      self.receiver.stop()
      self.receiver.close()

   def shutdown_hook(self, t_id, child):
       print '%s - Unexpected thread shutdown, handle this.. restart thread?' % str(t_id))

class MessageReceiver(Thread):


   def __init__(self,shutdown_hook = None):
     Thread.__init__(self)
     self.receiver = Receiver()
     self.shutdown_hook = shutdown_hook 


   def run(self):           
     #stop is a flag that i use to stop the thread...
     while(not stopped ):
      try:
        message  = self.receiver.pull()
        print "Message" + message   
      except ConnectionException as e:
         if stopped:
            #we are in the process of stopping
            pass
         else:
            self.shutdown_hook(self.iden, e)
            break
      finally:
            receiver.close()
0 голосов
/ 15 февраля 2011

Какая функция в конечном итоге ожидает прихода сообщения?Скорее всего, есть способ увеличить время ожидания и, таким образом, периодически проверять флаг завершения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...