socketpair和forking中的FD重用

时间:2014-08-08 09:16:59

标签: python sockets

我尝试编程prefork服务器进行研究,我发现os.fork将重用FD编号。

虽然输出是正确的,但我受伤的是为什么

这是代码和输出

#!/usr/bin/env python
# encoding: utf-8

import os
import socket
import time

def main():


    for x in xrange(4):
        parent_sock, children_sock = socket.socketpair()
        #parent_sock.setblocking(0)
        #children_sock.setblocking(0)
        pid = os.fork()

        if pid != 0:
            print os.getpid(), "M->parent", parent_sock.fileno()
            print os.getpid(), "M->children", children_sock.fileno()
            parent_sock.send('HI %d' % pid)

        else:
            #child
            print os.getpid(), "C->parent", parent_sock.fileno()
            print os.getpid(), "C->child", children_sock.fileno()
            time.sleep(3)
            print children_sock.fileno(), children_sock.recv(4096)
            return


if __name__ == '__main__':
    main()

你可以看到它只是一个正常的preforking服务器代码,我使用time.sleep来禁用python销毁child_sock。 但是为什么使用fileno 4,6的两个孩子处理仍然得到正确的答案?

$python fork.py
16414 M->parent 3
16414 M->children 4
16415 C->parent 3
16415 C->child 4
16414 M->parent 5
16414 M->children 6
16416 C->parent 5
16416 C->child 6
16414 M->parent 3
16414 M->children 4
16417 C->parent 3
16417 C->child 4
16414 M->parent 5
16414 M->children 6
16418 C->parent 5
16418 C->child 6

$4 HI 16415
6 HI 16416
4 HI 16417
6 HI 16418

1 个答案:

答案 0 :(得分:1)

垃圾收集。

在父级的每个for次迭代中,局部变量parent_sockchildren_sock指向新创建的套接字,并且以前的值不再可用,因此Python可以选择关闭重用旧套接字。

如果你将所有套接字存储在某个地方,它会阻止Python进行垃圾收集,因此它不会关闭它们,你会看到不同的数字。

我的意思是:这段代码可以重用一些FD号码:

for x in xrange(4):
    parent_sock, children_sock = socket.socketpair()
    print "M->parent", parent_sock.fileno()
    print "M->children", children_sock.fileno()

但是这段代码不能:

list_sockets = []
for x in xrange(4):
    parent_sock, children_sock = socket.socketpair()
    list_sockets.append([parent_sock, children_sock])
    print "M->parent", parent_sock.fileno()
    print "M->children", children_sock.fileno()