我在python中学习多处理.我尝试了多处理,在读完多处理模块的源代码之后,我发现它使用了os.fork(),所以我写了一些代码来测试os.fok(),但是我被困了.我的代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time
for i in range(2):
print '**********%d***********' % i
pid = os.fork()
print "Pid %d" % pid
Run Code Online (Sandbox Code Playgroud)
我认为每次打印都会执行两次,但执行三次.我无法理解这是如何工作的?我读过这个需要知道fork是如何工作的?
从这篇文章中说它也将被执行两次,所以我被困......
344*_*442 41
首先,删除该print '******...'行.它只会让每个人感到困惑.相反,让我们试试这段代码......
import os
import time
for i in range(2):
print "I'm about to be a dad!"
time.sleep(5)
pid = os.fork()
if pid == 0:
print "I'm {}, a newborn that knows to write to the terminal!".format(os.getpid())
else:
print "I'm the dad of {}, and he knows to use the terminal!".format(pid)
os.waitpid(pid)
Run Code Online (Sandbox Code Playgroud)
好的,首先,什么是"分叉"?Fork是现代和标准兼容的操作系统的一个特性(除了M $ Windows:操作系统的笑话几乎都是现代的和符合标准的)允许进程(又名:"程序",包括Python解释器) !)从字面上完全复制自己,有效地创建一个新的过程("程序"的另一个实例).一旦魔术完成,两个过程都是独立的.改变其中一个中的任何内容都不会影响另一个.
用于拼写这种黑暗和古老咒语的过程被称为父过程.这种对生命本身的憎恶的无灵魂结果被称为儿童过程.
对于所有人来说都是显而易见的,包括那些不是的人,你可以成为那些通过手段卖掉灵魂的精选程序员的一员os.fork().该功能执行分叉操作,因此导致第二个过程是凭空创建的.
现在,这个函数返回了什么,或者更重要的是,它甚至如何返回?如果你不想变得疯狂,请不要去阅读Linux内核的/kernel/fork.c文件!一旦内核完成我们知道它必须做的事情,但我们不想接受它,os.fork()在两个进程中返回!是的,甚至复制了调用堆栈!
那么,如果它们是精确的副本,父母和孩子之间的差异如何?简单.如果结果os.fork()为零,那么你就是在孩子身上工作.否则,您正在父项中工作,返回值是子项的PID(进程标识符).无论如何,孩子可以从中获得自己的PID os.getpid(),不是吗?
现在,考虑到这一点,以及在fork()循环内部进行混乱的事实,这就是发生的事情.让我们将原始流程称为"主"流程......
i = 0分成小孩 - #1-of-master
i = 1孩子 - #1-of-master:分叉为孩子 - #1-of-child-#1-of-masterfor循环,退出for循环,退出i = 1分成小孩 - #2-of-master
i = 1孩子 - #2-of-master:分叉为孩子 - #1-of-child-#2-of-masterfor循环,退出for循环,退出for循环,退出正如您所看到的,共有6个父/子打印来自4个独特的过程,产生6行输出,类似于......
我是12120的爸爸,他知道要使用终端!
我是12120,一个知道要写到终端的新生儿!
我是12121的爸爸,他知道要使用终端!
我是12121,一个知道要写到终端的新生儿!
我是12122的父亲,他知道要使用终端!
我是12122,一个知道要写到终端的新生儿!
但这只是武断的,它可能会输出这个......
我是12120,一个知道要写到终端的新生儿!
我是12120的爸爸,他知道要使用终端!
我是12121,一个知道要写到终端的新生儿!
我是12121的爸爸,他知道要使用终端!
我是12122,一个知道要写到终端的新生儿!
我是12122的父亲,他知道要使用终端!
或者其他任何东西.操作系统(和你的主板的时髦时钟)是唯一负责进程获取时间片的顺序的,所以如果你不喜欢内核如何组织你的进程,那么就要归咎于Torvalds(并期望在返回时没有自我推销) ;) .
我希望这对你有所启发!
glg*_*lgl 26
要直接回答这个问题,os.fork()可以通过调用底层的OS函数来实现fork().
但你肯定对它的作用感兴趣.那么这会创建另一个过程,它将在与此完全相同的位置恢复.因此,在第一个循环运行中,你得到一个fork,之后你有两个进程,"原始的"(获取pid子进程的PID的值)和分叉的进程(获取pid值0).
它们都打印它们的pid值并继续第二次循环运行,它们都打印出来.然后他们都分叉,留下4个进程,这些进程都打印各自的pid值.其中两个应该是0,其他两个应该是他们刚创建的孩子的PID.
将代码更改为
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time
for i in range(2):
print '**********%d***********' % i
pid = os.fork()
if pid == 0:
# We are in the child process.
print "%d (child) just was created by %d." % (os.getpid(), os.getppid())
else:
# We are in the parent process.
print "%d (parent) just created %d." % (os.getpid(), pid)
Run Code Online (Sandbox Code Playgroud)
你会看到更好的结果:每个进程都会告诉你它自己的PID以及fork上发生了什么.
| 归档时间: |
|
| 查看次数: |
29128 次 |
| 最近记录: |