我尝试编程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
答案 0 :(得分:1)
垃圾收集。
在父级的每个for
次迭代中,局部变量parent_sock
和children_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()