tcp通信:多进程共享listen socket方式

原文链接:http://blog.csdn.net/largetalk/article/details/7939080

看tornado源码多进程(process.py)那段,发现他的多进程模型和一般常见的模型有点不一样,多见的是主进程bind-> listen -> accept, 将accept返回的socket用子进程处理,而tornado是在bind -> listen -> fork, 在listen之后fork,多个子进程共享listen socket, 每个子进程都accept。 以前没见过这种模型,开始觉的会有 错误或"惊群“现象的发生,网上找了一下也没有找到相关资料,自己就写了个程序测试一下。

 

[python] view plaincopyprint?
 
  1. import socket  
  2. import select  
  3. import os  
  4. import time  
  5. import errno  
  6.   
  7. def child_epoll():  
  8.     epoll = select.epoll()  
  9.     epoll.register(sock.fileno(), select.EPOLLIN)  
  10.     try:  
  11.         while True:  
  12.             events = epoll.poll(1)  
  13.             for fileno, event in events:  
  14.                 if fileno == sock.fileno():  
  15.                     connection, address = sock.accept()  
  16.                     print os.getpid(), address  
  17.                     time.sleep(1)  
  18.                     connection.close()  
  19.     finally:  
  20.         epoll.unregister(sock.fileno())  
  21.         epoll.close()  
  22.   
  23.   
  24. def start_child(i):  
  25.     pid = os.fork()  
  26.     if pid == 0:  
  27.         child_epoll()  
  28.     else:  
  29.         children[pid] = i  
  30.   
  31. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)  
  32. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  
  33. sock.setblocking(0)  
  34. sock.bind(("0.0.0.0", 9700))  
  35. sock.listen(128)  
  36.   
  37.   
  38. children = {}  
  39.   
  40. for i in range(4):  
  41.     start_child(i)  
  42.   
  43. time.sleep(2)  
  44. print children  
  45. while children:  
  46.     try:  
  47.         pid = status = os.wait()  
  48.     except OSError, e:  
  49.         if e.errno ==  errno.EINTR:  
  50.             continue  
  51.         raise  
  52.     if pid not in children:  
  53.         continue  
  54.     children.pop(pid)  
  55.   
  56. sys.exit(0)  


然后用ab简单测测: ab -n 10 -c 5 http://127.0.0.1:9700/

 

 

可以发现每个连接都会只有一个进程去处理。虽然逻辑上没有错误,但还是要找相关资料看看,有知道的请告诉我一下。

 

后补:(20121101)

http://blog.dccmx.com/2011/02/nginx-conn-handling/ 介绍nginx多进程模型就是如此工作,nginx使用一个全局锁来避免惊群

http://static.usenix.org/event/usenix2000/freenix/full_papers/molloy/molloy.pdf 该论文说linux 2.6内核之后accept不会有惊群现象

posted @ 2014-09-13 13:00  johnny_HITWH  阅读(954)  评论(0编辑  收藏  举报