laixintao / python-parallel-programming-cookbook-cn

📖《Python Parallel Programming Cookbook》中文版
http://python-parallel-programmning-cookbook.readthedocs.io/
1.49k stars 93 forks source link

第三章第四节存在根本性错误 #96

Open Gordonzxr opened 4 months ago

Gordonzxr commented 4 months ago

此章节关于如何在后台运行一个进程,其中的范例存在根本性错误。

import multiprocessing
import time

def foo():
    name = multiprocessing.current_process().name
    print("Starting %s " % name)
    time.sleep(3)
    print("Exiting %s " % name)

if __name__ == '__main__':
    background_process = multiprocessing.Process(name='background_process', target=foo)
    background_process.daemon = True
    NO_background_process = multiprocessing.Process(name='NO_background_process', target=foo)
    NO_background_process.daemon = False
    background_process.start()
    NO_background_process.start()

其中,守护进程的生命周期是跟随父进程的,当主进程结束,其创建的守护进程也随之结束,而非守护进程则会继续运行,如果尝试对守护进程使用join()或者让主进程在创建完两个子进程后保持一段时间,会发现守护进程也会有屏幕输出。

import multiprocessing
import time

def foo():
    name = multiprocessing.current_process().name
    print("Starting %s " % name)
    time.sleep(3)
    print("Exiting %s " % name)

if __name__ == '__main__':
    background_process = multiprocessing.Process(name='background_process', target=foo)
    background_process.daemon = True
    NO_background_process = multiprocessing.Process(name='NO_background_process', target=foo)
    NO_background_process.daemon = False
    background_process.start()
    NO_background_process.start()
    time.sleep(10)
laixintao commented 4 months ago

没看懂你想指出的错误是什么。可以重新描述下吗?

文中描述的是:

实际的表现应该是:

Gordonzxr commented 2 months ago

没看懂你想指出的错误是什么。可以重新描述下吗?

文中描述的是:

实际的表现应该是:

是这样的,最上面的是书中的例子,在这个例子里,可以看到我们定义了两个线程——一个普通线程和一个守护线程。 在书中的阐述里,守护线程不会有自己的控制台输出,所输出的只有普通线程。 然而,守护线程没有输出的原因并非是书中所描述的——该线程是一个“后台”线程,“后台运行的没有输出”,而是因为当主线程运行到background_process.start()和NO_background_process.start()之后就结束了,而守护线程的生命周期是跟随主线程一致的,也就是说,当主线程结束的时候,普通线程还可继续运行进行输出,而守护线程还没运行到print()的时候就已经和主线程一同结束了。 守护线程没有控制台输出的原因并非是它是“后台”的。 如果在原例结尾增加可以维持主线程运行的sleep,会发现守护线程也有自己的屏幕输出。

laixintao commented 2 months ago

在非后台运行的进程会看到一个输出,后台运行的没有输出,后台运行进程在主进程结束之后会自动结束。

这里想说的就是 「当主线程结束的时候,普通线程还可继续运行进行输出,而守护线程还没运行到print()的时候就已经和主线程一同结束了。」

不是说因为是后台进程而没有输出。