简体   繁体   中英

Python thread.Timer() not works in my process

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

this is test code.

the result:

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

If I use test.say_hello_again_and_again() , "Hello :D" is printed repeatedly.

But, process is not working as I expected. Why is "Hello :D" not being printed in my process?

What's happening in my process?

There are two problems with your code:

First: You start a process with start() . This is doing a fork , that means now you have two processes, the parent and the child running side by side. Now, the parent process immediately exits, because after start() it's the end of the program. To wait until the child has finished (which in your case is never), you have to add process.join() .

I did test your suggestion, but it not works

Indeed. There is a second issue: You start a new thread with threading.Timer(1, ...).start() but then immediately end the process. Now, you don't wait until your thread started because the underlying process immediately dies. You'd need to also wait until the thread has stopped with join() .

Now that's how your program would look like:

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

But this is suboptimal at best because you mix multiprocessing (which is using fork to start independent processes) and threading (which starts a thread within the process). While this is not really a problem it makes debugging a lot harder (one problem eg with the code above is that you can't stop it with ctrl-c because of some reason your spawned process is inherited by the OS and kept running). Why don't you just do this?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM