该程序启动两个进程。看起来实际上可能为每个进程创建了两个线程。一个是生成的 python 程序的主线代码,另一个是调用来启动进程的函数的执行。 程序输出显示每个进程中运行的程序主线以及运行生成进程时指定的被调用函数。
每个进程的主线以进程ID的显示结束。两个生成的任务中的每一个也会通过显示其进程 ID 来终止。日志显示首先打印主线消息,然后调用生成的函数。
from multiprocessing import Process
import os
import psutil
def f(name):
print('\nStarting process ID:', os.getpid())
print ('I am process with argument: ', name)
print ('parent: ', os.getppid())
print ('process name: ', psutil.Process().name())
if __name__ == '__main__':
print ('\nMain process ID:', os.getpid(), '\n')
p = Process(target=f, name='process-1', args=('passed-name1',))
p.start()
p.join()
print ('\nAfter 1st join, PID:', os.getpid(),'\n')
p = Process(target=f, name='process-2', args=('passed-name2',))
p.start()
p.join()
print ('\nAfter 2 joins, PID:',os.getpid(),'\n')
print ('End mainline code for PID',os.getpid())
我希望当进程完成其操作时会出现“在任务结束时执行”消息。但我发现它在运行进程的主线代码之前执行。
这是该程序的输出:
Main process ID: 5528
End mainline code for PID: 42368
Starting process ID: 42368
I am process with argument: passed-name1
parent: 5528
process name: python.exe
After 1st join, PID: 5528
End mainline code for PID: 17764
Starting process ID: 17764
I am process with argument: passed-name2
parent: 5528
process name: python.exe
After 2 joins, PID: 5528
End mainline code for PID: 5528
问题 1:那么 Process() 函数是否会生成整个程序并将命名函数作为单独的进程运行?
问题2:当我专门为每个进程命名了一个名称来调用它时,为什么进程名为“python.exe”?
现在的另一个问题是多处理困境。如果添加代码
exit(0)
作为代码的最后一行,在打印终止消息之后,两个衍生任务的主线根本不执行。如果将 exit(0) 添加为最后一行,则以下是代码的输出:
Main process ID: 36996
End mainline code PID: 39976
After 1st join, PID: 36996
End mainline code PID: 28324
After 2 joins, PID: 36996
End mainline code PID: 36996
因此每个进程的主线代码都运行了,但 Process() 函数调用的函数却没有运行。
我还注意到,如果我不调用 exit(0),而是导入 time 并调用 time.sleep(5),则会出现“主线结束”消息,然后在 5 秒延迟后执行生成任务的主线代码。我本希望被调用的函数立即启动。对于执行看起来像是进程的两个线程来说,这似乎令人困惑。或者它可能执行主线,然后执行被调用的函数。但理解这一点很重要,因为与 Process() 调用中调用的函数相比,进入主线的代码变得更加复杂。
那么
函数是否会生成整个程序以及将命名函数作为单独的进程运行?Process()
不,
Process()
函数不会生成整个程序,而是创建仅执行特定函数(目标)的单独进程。就你而言 - f(name)
。
但是在 multiprocessing.Process()
一个新进程从定义它的模块中导入代码之后(在您的情况下为 __main__
),这就是为什么看起来所有整个代码都再次运行,而是只执行 if __name__ == '__main__'
中的代码。
当我专门为每个进程命名了一个名称来调用它时,为什么进程名为“python.exe”?
psutil.Process().name()
打印执行程序文件的名称。 (对于所有 Python 进程来说都是 python.exe
)。要打印进程名称,您可以在函数内部使用 multiprocessing.current_process().name
:
from multiprocessing import Process, current_process
import os
def f(name):
print('\nStarting process ID:', os.getpid())
print ('I am process with argument: ', name)
print ('parent: ', os.getppid())
print ('process name: ', current_process().name)
当您调用 exit(0) 时,它会导致程序和程序的所有进程立即终止,因此 f(name) 没有足够的时间运行。但使用 time.sleep(5) 确实有足够的时间。这就是为什么你可以看到 f(name) 的输出