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()