2014-09-03 8 views
3

Я использую класс процессов многопроцессорного модуля для запуска нескольких процессов, эти процессы выполняют некоторый скрипт и затем умирают. Что я хотел, тайм-аут, который должен применяться к каждому процессу, так что процесс умрет, если не удается выполнить во время тайм-аут. Я использую join(timeout) для объектов процесса. Since the join() function doesn;t kill the process, it just blocks the process until it finishesИспользование join() для процессов, созданных с использованием многопроцессорности в python

Теперь мой вопрос: Есть ли какие-либо побочные эффекты использования join() с timeout ..like, будут очищены процессы автоматически, после того, как основной процесс умирает ?? или я должен убить эти процессы вручную?

Я новичок в python и его многопроцессорном модуле, будьте терпеливы.


Мой код, который создает процессы в цикле ::

q = Queue() 
jobs = [ 
     Process(
      target=get_current_value, 
      args=(q,), 
      kwargs= 
      { 
       'device': device, 
       'service_list': service_list, 
       'data_source_list': data_source_list 
       } 
      ) for device in device_list 
     ] 
for j in jobs: 
     j.start() 
for k in jobs: 
     k.join() 
+0

Почему вы не используете сигнальный модуль? https://docs.python.org/2/library/signal.html см. этот вопрос: http://stackoverflow.com/questions/492519/timeout-on-a-python-function-call – Kasramvd

+0

Вопрос, кажется, работа с потоками ... Я использую многопроцессы, хотя – dotslash

+0

Каковы фактически выполняемые дочерние процессы? Они * потребляют * из «очереди» вообще? – dano

ответ

0

join() ничего не делает с дочерним процессом. Если вы действительно хотите прекратить рабочий процесс не чистым способом, вы должны использовать terminate() (вы должны понимать последствия). Если вы хотите, чтобы дети были прекращены, когда основной процесс завершен, вы должны установить атрибут daemon.

+0

Я не хочу идти с нечистым способом. Я хочу, чтобы мой основной процесс убивал эти дочерние процессы которые занимают больше времени .... любой ключ, как идти с этим ?? – dotslash

+1

Либо вы убиваете процессы, либо попросите их закончить чисто, скорее всего, используя любые каналы, которые вы уже используете для передачи данных (например, очереди) или других способов IPC. Вы не можете полностью отключить процесс (или поток, если на то пошло) извне. – wRAR

+0

Я передаю общую очередь каждому процессу и обрабатываю его результат в очередь .... Как я могу убить/завершить процесс с помощью этой очереди? ... довольно запутанно для меня – dotslash

1

timeout аргумент просто говорит join, как долго ждать, чтобы выйти Process, прежде чем давать. Если timeout истекает, Process не выйдет; вызов join просто разблокируется. Если вы хотите закончить своих работников, когда истекает время ожидания, вам нужно сделать это вручную. Вы можете использовать terminate, как это было предложено wRAR, чтобы нечистоплотный остановов, или какой-то другой механизм сигнализации сказать детям выключит чисто:

p = Process(target=worker, args=(queue,)) 
p.start() 
p.join(50) 
if p.isalive(): # join timed out without the process actually finishing 
    #p.terminate() # unclean shutdown 

Если вы не хотите использовать terminate, альтернатива подход действительно зависит от того, что делают рабочие. Если они потребляют из очереди, вы можете использовать часовой:

def worker(queue): 
    for item in iter(queue.get, None): # None will break the loop 
     # Do normal work 

if __name__ == "__main__": 
    queue = multiprocessing.Queue() 
    p = multiprocessing.Process(target=worker, args=(queue,)) 
    p.start() 
    # Do normal work here 

    # Time to shut down 
    queue.put(None) 

Или вы могли бы использовать Event, если вы делаете некоторые другие операции в цикле:

def worker(event): 
    while not event.is_set(): 
     # Do work here 

if __name__ == "__main__": 
    event= multiprocessing.Event() 
    p = multiprocessing.Process(target=worker, args=(event,)) 
    p.start() 
    # Do normal work here 

    # Time to shut down 
    event.set() 

Использованием terminate может быть просто отлично, если только ваши дочерние процессы не используют ресурсы, которые могут быть повреждены, если процесс неожиданно отключен (например, запись в файл или db или блокировка). Если вы просто делаете некоторые вычисления у работника, использование terminate ничего не повредит.

+0

Я уже использую первый подход, предложенный вами ... но соединение (тайм-аут) не работает, когда я создаю процессы в цикле for, его штраф только за один процесс – dotslash

+0

Должен ли я опубликовать код, который создает процессы в цикле for? – dotslash

+0

@Zira Да, пожалуйста, внесите изменения в свой вопрос. Похоже, вам нужно поместить процессы в список при их запуске, а затем вызвать «присоединиться» ко всем к магазинам после того, как все они были запущены. – dano

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