我得到了这段代码,为了更好地理解它,我添加了一行代码来跟踪pid等于零的位置:
import os, time
def counter(count): # run in new process
for i in range(count):
time.sleep(0.00001) # simulate real work
print('[%s] => %s' % (os.getpid(), i))
for i in range(5):
pid = os.fork()
print("The pid is: ", pid)# the one I added
if pid != 0:
print('Process %d spawned' % pid) # in parent: continue
else:
counter(5) # else in child/new process
os._exit(0) # run function and exit
print('Main process exiting.')
问题:
1)什么激活呼叫计数器?新进程是否正在检查其pid,如果pid等于零,则调用计数器?你知道吗
2)如果我将睡眠时间更改为1秒(而不是十分之一密耳),则不会打印子进程的数据。那背景是怎么回事?你知道吗
我得到这个结果:
the pid is: 6
Prociss 6 spawned
the pid is: 7
Prociss 7 spawned
the pid is: 8
Prociss 8 spawned
the pid is: 9
Prociss 9 spawned
the pid is: 10
Prociss 10 spawned
Main prociss exiting.
the pid is: 0
the pid is: 0
the pid is: 0
the pid is: 0
[6] => 0
[8] => 0
[7] => 0
[6] => 1
the pid is: 0
[8] => 1
[6] => 2
[7] => 1
[9] => 0
[6] => 3
[8] => 2
[7] => 2
[9] => 1
[8] => 3
[6] => 4
[7] => 3
[8] => 4
[7] => 4
[9] => 2
[10] => 0
[9] => 3
[10] => 1
[9] => 4
[10] => 2
[10] => 3
[10] => 4
...Program finished with exit code 0
回答你的两个问题:
是的。
os.fork()
是一种不寻常的野兽,因为它“违反了物理定律”:它在两个不同的过程中返回两次。这两个进程(几乎)是相同的,因此要知道您是哪一个进程(父进程还是子进程)的唯一方法是查看os.fork()
返回了什么:如果它返回零,您就是子进程,否则返回值就是子进程的pid。你知道吗由于两个进程都执行
if pid != 0
行,因此pid为零的进程(即子进程)将执行else
块,该块将调用counter
。你知道吗你不是为了你的孩子。这意味着一旦父进程退出,它就会“孤立”其所有子进程。
init
将有助于采用它们,但在这个过程中它们可能会失去对其控制终端的访问权限,仅此一点就足以杀死它们。另外,在现代的Linux系统上,systemd
如果你没有告诉它其他的话,很可能会杀死孩子们。你知道吗通常,如果您使用的是
fork
,那么还需要wait
。父级获取被分叉的子级的pid,以便它可以调用该pid上的wait
。这样做有两个目的:第一,它实际上是等待子进程执行完毕,第二,它将允许父进程从子进程接收退出代码,这将允许您知道子进程是成功退出还是被杀死。如果你不等待,就没有100%可靠的方法知道孩子发生了什么。(即使您将pid存放在其他地方,也有可能在有机会再次检查之前重新使用pid。)在
fork
/(exec
)/wait
的舞蹈中有很多微妙之处;它们的简单中有一种优雅,但如果你接触这些工具,就会有很多假定的知识。如果你还没有阅读任何关于fork
的教程,就不要指望能有效地使用它。如果您不想成为Unix进程模型(以及信号处理、控制终端和会话领导者等)方面的专家,那么最好使用更高级别的抽象来解决问题,而不是像这样纠缠于低级别的东西。Python提供了multiprocessing
模块来帮助实现这一点,这是一个更好的通用工具。你知道吗相关问题 更多 >
编程相关推荐