Python thread.Timer() не работает в моем процессе

import os
import sys
from multiprocessing import Process, Queue
import threading

class Test:
  def __init__(self):
    print '__init__ is called'

  def say_hello_again_and_again(self):
    print 'Hello :D'
    threading.Timer(1, self.say_hello_again_and_again).start()


test = Test()
#test.say_hello_again_and_again()
process = Process(target=test.say_hello_again_and_again)
process.start()

это тестовый код.

результат:

pi@raspberrypi:~/Plant2 $ python test2.py
__init__ is called
Hello :D

Если я использую test.say_hello_again_and_again(), "Привет: D" печатается неоднократно.

Но процесс не работает, как я ожидал. Почему "Hello:D" не печатается в моем процессе?

Что происходит в моем процессе?

1 ответ

Решение

Есть две проблемы с вашим кодом:

Первый: вы начинаете процесс с start(), Это делает fork, это означает, что теперь у вас есть два процесса, родительский и дочерний, работающие рядом. Теперь родительский процесс немедленно завершается, потому что после start() это конец программы. Чтобы подождать, пока ребенок не закончит (чего в вашем случае никогда не бывает), вы должны добавить process.join(),

Я проверил ваше предложение, но оно не работает

В самом деле. Существует вторая проблема: вы начинаете новую тему с threading.Timer(1, ...).start() но затем немедленно завершите процесс. Теперь вы не ждите, пока начнется ваш поток, потому что основной процесс немедленно умирает. Вам также нужно подождать, пока поток не остановится с join(),

Вот как будет выглядеть ваша программа:

from multiprocessing import Process
import threading

class Test:
  def __init__(self):
    print '__init__ is called'

  def say_hello_again_and_again(self):
    print 'Hello :D'
    timer = threading.Timer(1, self.say_hello_again_and_again)
    timer.start()
    timer.join()

test = Test()
process = Process(target=test.say_hello_again_and_again)
process.start()
process.join()

Но это в лучшем случае неоптимально, потому что вы смешиваете многопроцессорность (которая использует fork запускать независимые процессы) и многопоточность (которая запускает поток внутри процесса). Хотя это на самом деле не проблема, это значительно усложняет отладку (например, с помощью приведенного выше кода проблема заключается в том, что вы не можете остановить его с помощью ctrl-c, потому что по какой-то причине ваш порожденный процесс наследуется ОС и продолжает работать). Почему бы тебе просто не сделать это?

from multiprocessing import Process, Queue
import time

class Test:
  def __init__(self):
    print '__init__ is called'

  def say_hello_again_and_again(self):
    while True:
        print 'Hello :D'
        time.sleep(1)

test = Test()
process = Process(target=test.say_hello_again_and_again)
process.start()
process.join()
Другие вопросы по тегам