Потоки в скрученном …, как использовать их правильно?

Я должен записать простое приложение, которое выполняет два потока: - поток 1: выполнения в синхронизированные периоды, скажем, каждая 1 минута - распараллеливает 2: просто 'нормальное', в то время как Истинный цикл, который действительно 'наполняет'

если бы не требование для выполнения в синхронизированном интервале я не посмотрел бы на скрученный вообще, но простой сон (60) не достаточно хорош и конструкция как:

l = task.LoopingCall(timed_thread)
l.start(60.0)
reactor.run()

Посмотревший действительно простой достигнуть того, что я хотел там.

Теперь, как я 'правильно' добавляю другой поток?

Я вижу две опции здесь:

  • Пользуйтесь библиотекой поточной обработки и выполните два 'потока Python' одно выполнение моего цикла с условием продолжения и другое выполнение reactor.run (). Но Google, кажется, возражает этому подходу и предлагает использовать скрученную поточную обработку
  • Используйте скрученную поточную обработку. Это - то, что я попробовал, но так или иначе это смотрит бит, неуклюжий мне.

Вот то, что я придумал:

def timed_thread():
    print 'i will be called every 1 minute'
    return

def normal_thread():
    print 'this is a normal thread'
    time.sleep(30)
    return

l = task.LoopingCall(timed_thread)
l.start(60.0)
reactor.callInThread(normal_thread)
reactor.run()

Это, кажется, работает, но! Я не могу остановить приложение. Если бы я нажимаю ^C, он ничего не сделал бы (без 'callInThread', который он просто останавливает, поскольку Вы ожидали бы это к). ^Z разбомбил для окружения, и если я тогда 'уничтожаю %1', это, кажется, уничтожает процесс (оболочка сообщает, что), но 'нормальный' поток продолжает работать. уничтожьте PID, не избавился бы от него, и единственное средство исправления является уничтожением-9. Действительно странный.

Так. Что я делаю неправильно? Действительно ли это - корректный подход для реализации двух потоков в скрученном? Разве я не должен беспокоиться скрученным? Что другие 'стандартные' альтернативы должны реализовать синхронизированные вызовы? ('Стандарт', я подразумеваю, что могу easy_install или конфетка, устанавливает их, я не хочу начинать загружать и использовать некоторые случайные сценарии от случайных веб-страниц).

9
задан rytis 11 February 2010 в 08:58
поделиться

2 ответа

Предполагая, что ваш main относительно неблокирующий:

import random
from twisted.internet import task

class MyProcess:
  def __init__(self):
    self.stats = []
    self.lp = None
  def myloopingCall(self):
    print "I have %s stats" % len(self.stats)
  def myMainFunction(self,reactor):
    self.stats.append(random.random())
    reactor.callLater(0,self.myMainFunction,reactor)
  def start(self,reactor):
    self.lp = task.LoopingCall(self.myloopingCall)
    self.lp.start(2)
    reactor.callLater(0,self.myMainFunction,reactor)
  def stop(self):
    if self.lp is not None:
      self.lp.stop()
    print "I'm done"

if __name__ == '__main__':
  myproc = MyProcess()
  from twisted.internet import reactor
  reactor.callWhenRunning(myproc.start,reactor)
  reactor.addSystemEventTrigger('during','shutdown',myproc.stop)
  reactor.callLater(10,reactor.stop)
  reactor.run()
$ python bleh.py
I have 0 stats
I have 33375 stats
I have 66786 stats
I have 100254 stats
I have 133625 stats
I'm done
2
ответ дан 4 December 2019 в 23:06
поделиться

Вы не объяснили, зачем вам на самом деле нужны потоки. Если бы вы объяснили, я бы смог объяснить, почему они вам не нужны. ;)

Что касается этого, я могу подтвердить, что ваше базовое понимание вещей верно. Одно возможное недоразумение, которое я могу прояснить, это представление о том, что "потоки python" и "потоки Twisted" вообще отличаются друг от друга. Это не так. Python предоставляет библиотеку потоков. Все API потоков Twisted реализованы в терминах библиотеки потоков Python. Отличается только API.

Что касается завершения работы, у вас есть два варианта.

  • Запустить свой вечный поток, используя API потоков Python напрямую, и сделать этот поток демоном. Ваш процесс может завершиться, даже если потоки демона все еще запущены. Возможная проблема этого решения заключается в том, что некоторые версии Python имеют проблемы с демонскими потоками, что может привести к аварийному завершению процесса.
  • Создайте свой поток, используя либо API Twisted, либо API потоков stdlib, но при этом добавьте крючок выключения Twisted, используя reactor.addSystemEventTrigger('before', 'shutdown', f). В этом хуке установите связь с рабочим потоком и скажите ему выключиться. Например, вы можете разделить threading.Event между потоком Twisted и вашим рабочим потоком, а хук установить его. Рабочий поток может периодически проверять, был ли он установлен, и завершать работу, когда заметит, что он был установлен. Помимо отсутствия сбоев, это дает еще одно преимущество перед потоками-демонами - это позволит вам выполнить некоторый код очистки или завершения в рабочем потоке перед завершением процесса.
5
ответ дан 4 December 2019 в 23:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: