简体   繁体   English

Python thread.Timer()在我的进程中不起作用

[英]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. 如果使用test.say_hello_again_and_again() ,则会重复打印“ Hello:D”。

But, process is not working as I expected. 但是,过程没有按我预期的那样工作。 Why is "Hello :D" not being printed in my process? 为什么在我的过程中没有打印“ Hello:D”?

What's happening in my process? 我的过程中发生了什么?

There are two problems with your code: 您的代码有两个问题:

First: You start a process with start() . 首先:使用start()启动一个进程。 This is doing a fork , that means now you have two processes, the parent and the child running side by side. 这是在做一个fork ,这意味着现在您有两个进程,父进程和子进程并排运行。 Now, the parent process immediately exits, because after start() it's the end of the program. 现在,父进程立即退出,因为在start()它是程序的结尾。 To wait until the child has finished (which in your case is never), you have to add process.join() . 要等到孩子完成任务(在您的情况下是永远不会完成)之前,您必须添加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. 还有第二个问题:您可以使用threading.Timer(1, ...).start()启动一个新线程,然后立即结束该进程。 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() . 您还需要等待,直到使用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). 但这充其量不是最佳选择,因为您将多重处理(使用fork来启动独立进程)和线程(在进程内启动线程)混合在一起。 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). 尽管这并不是真正的问题,但是它会使调试工作变得更加困难(例如,上面的代码存在一个问题,就是由于某些原因,您生成的进程已被OS继承并保持运行,因此您无法使用ctrl-c停止它)。 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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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