Python论坛  - 讨论区

标题:[zeuux-py:175] Re: 请教一个关于pipe和fork的问题

2009年09月24日 星期四 16:46

SUN Guonian sun在cnnic.cn
星期四 九月 24 16:46:30 CST 2009

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

TianCruz wrote:
> 在百度搜索到关于pipe和fork的一段话:
>  
> fork()不仅创建出与父进程代码相同的子进程,而且父进程在fork执行点的所有上
> 下文场景也被自动复制到子进程中,包括:
> ―全局和局部变量
> ―打开的文件句柄
> ―共享内存、消息等同步对象
>   由于pipe调用相当于创建了2个文件句柄,因此在fork后这两个句柄也被自动复
> 制到子进程中,对这两个句柄的操作效果与在主进程中的操作效果是一致的,这就
> 使父子进程之间很容易通过该机制实现数据交换,如:
>   假设pipe产生的句柄为P[0],P[1],在fork后父子进程都拥有了P[0],P[1]句柄,
> 那么:
> ―父进程可向自己的P[1]中写入数据,子进程从P[0]中即可读出该数据;切记此时
> 父进程不能也从P[0]读数据,否则自己写入的数据可能先被自己读走了
> ―反之亦然,子进程向P[1]中写入数据后,父进程从P[0]中可读出该数据;切记此
> 时子进程不要从P[0]读走数据
>   你可能难以理解为什么进程内部的数据读写会被传递到另一个进程,但别忘了,
> pipe匿名管道和文件,socket等一样是属于操作系统的管理对象,对其进行读写都
> 是由OS的内核代码来进行控制的。在父进程调用pipe创建出管道后,该管道对象是
> 存储在OS内部的,父进程得到的P[0]和P[1] 都只是对该对象的引用(相当于指
> 针);在fork出子进程后,子进程复制出的也只是同一个指针,所指向的还是OS中
> 的同一个对象,这就是为什么父子进程能通过其进行互相通信的原因。
>  
> 理解上就是fork创建的子进程所拥有的pipe文件句柄和父进程的是一样的,在PP3E
> 上看到这样一段代码:
>  
> import os, time
> 
> def child(pipeout):
>     zzz = 0
>     while 1:
>         time.sleep(zzz)                          # make parent wait
>         os.write(pipeout, 'Spam %03d\n' % zzz)   # send to parent
>         zzz = (zzz+1) % 5                        # roll to 0 at 5
> 
> def parent( ):
>     pipein, pipeout = os.pipe( )                  # make 2-ended pipe
>     if os.fork( ) == 0:                            # in child, write to pipe
>         os.close(pipein)                          # close input side here
>         child(pipeout)
>     else:                                        # in parent, listen to pipe
>         os.close(pipeout)                        # close output side here
>         pipein = os .fdopen(pipein)               # make stdio input object
>         while 1:
>             line = pipein.readline( )[:-1]        # blocks until data sent
>             print 'Parent %d got "%s" at %s' % (os.getpid(), line,
> time.time( ))
> 
> parent( )
> 
> 那么按照上面的理解,父子进程操作的应该是同一个pipe;该段程序在父进程将
> pipein给close掉了,子进程又将该pipe的out端给close了;这样pipe的两个end都
> 被关掉了,那为什么父进程还能从pipeout 端读数据,子进程还能往pipein端写数
> 据呢???
> 
> ------------------------------------------------------------------------
> 使用新一代 Windows Live Messenger 轻松交流和共享! 立刻下载!
> <http://www.windowslive.cn/Messenger/>
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> zeuux-python mailing list
> zeuux-python at zeuux.org
> http://www.zeuux.org/mailman/listinfo/zeuux-python

http://hell.org.ua/Docs/oreilly/other2/python2/Chapter%203.htm
有这么一段话:
This version has also been augmented to close the unused end of the pipe in each
process (e.g., after the fork, the parent process closes its copy of the output
side of the pipe written by the child); programs should close unused pipe ends
in general. Running with this new version returns a single child message to the
parent each time it reads from the pipe, because they are separated with markers
when written:

我的理解是关掉不必要的pipe端。就是作为一个单向通信的管道。

形象点的理解是:
1. fork()之前,是这个样子,
parent
pi ->|
     |
po <-|

2. fork()之后,是这个样子,
parent  child
pi ->|<- pi
     |
po <-|-> po

3. 关闭之后,是这个样子,
parent  child
pi ->|
     |
     |-> po

- --
孙国念

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkq7MeYACgkQkxxlPmOq+E3hqACfVvErin+FEu2GGC/fInHsTMem
aMQAn1ITRB0BHymj6Yjded4T8oZmJVye
=EqlP
-----END PGP SIGNATURE-----

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2024

    京ICP备05028076号