有人可以向我解释以下os.fork()示例吗?

时间:2014-06-05 05:24:31

标签: python parallel-processing

[代码来自Mark Lutz编程Python第4版]

"forks child processes until you type 'q'"
import os
def child():
    print('Hello from child', os.getpid())
    os._exit(0) # else goes back to parent loop

def parent():
    while True:
        newpid = os.fork()
        if newpid == 0:
            child()
        else:
            print('Hello from parent', os.getpid(), newpid)
        if input() == 'q': break

parent()

运行时代码输出的内容:

Hello from parent 2057 2062 
Hello from child 2062

Hello from parent 2057 2068 
Hello from child 2068

Hello from parent 2057 2069 
Hello from child 2069

Hello from parent 2057 2070 
Hello from child 2070 
q

我理解的事情:

  1. os.fork()用于与当前进程并行启动另一个进程。
  2. os.fork()创建上一个Python会话的副本并并行打开。
  3. os.fork()返回新进程的ID。
  4. 我不明白的事情:

    1. 当代码运行时,os.getpid()的值永远不会改变?
    2. 为什么要调用child()函数?假设newpid!= 0的值,那么程序将打印出print('Hello from parent', os.getpid(), newpid)。但是,之后,它会打印来自子节点的行而不是请求输入,因为大小写在if语句之后。
    3. os._exit(0)在做什么?
    4. 非常感谢你的时间。 :)

2 个答案:

答案 0 :(得分:6)

  

1:为什么代码运行时os.getpid()的值永远不会改变?

os.getpid()的值永远不会为父级更改,因为它始终是相同的进程。由于fork()始终使用自己的PID创建一个全新的子进程克隆,因此pid每次都会更改。

  

2:为什么调用child()函数?假设newpid!= 0的值,那么程序将打印出print('Hello from parent',os.getpid(),newpid)。但是,在那之后,它会打印来自子节点的行而不是请求输入,因为大小写在if语句之后。

调用子进程,因为现在有两个进程正在运行。一个称为child()函数,另一个称为print函数。他们只是打算在屏幕上打印,在这种情况下你看到父打印“胜利”。

  

3:os._exit(0)在做什么?

见这里:https://docs.python.org/2/library/os.html#os._exit

  

退出状态为n的进程,不调用清理处理程序,刷新stdio缓冲区等。

答案 1 :(得分:2)

  1. 因为您的父进程在运行时始终具有相同的pid(while True:)。
  2. 孩子实际上是父母的副本。这就是os.fork所做的!该函数将子项的pid返回给父项。所以父进程运行if else语句的第二部分,而所有子进程运行第一部分,因为子进程的os.fork返回0。
  3. os._exit基本上是os.exit()的精简版本,适用于子流程。