该代码会开启NPROCES 个进程来进行echo的服务,若其中一个退出,会马上创建一个新的进程进入进程池中,
而不是等待下一个客户端连接来的时候才创建新的进程。这样你就有了一个一直保持NPROCES 个进程的进程池。
当然,以下程序只是一个模型程序,用来实现该思想。在实际的网络编程过程中还需要在该模型上进行优化。
该模型对于一些要保持高可用的服务,或自动恢复的服务还是比较有用。
-
请注意python中进程中进程的回收和再生过程,不是简单的join
-
-
#!/usr/bin/env python
-
# encoding: utf-8
-
#
-
#-------------------------------------------------------------------------------
-
#
-
# 进程池实现socket server.
-
#
-
#-------------------------------------------------------------------------------
-
-
import os
-
import time
-
import socket
-
import multiprocessing as mp
-
from signal import signal, SIGINT, SIG_IGN, siginterrupt
-
from time import ctime
-
-
-
BUFSIZ = 1024
-
NPROCES = 8
-
-
-
def worker(listen_sock, ctlq, exit_flag):
-
#while True:
-
cli_sock, addr = listen_sock.accept()
-
-
if exit_flag.is_set():
-
ctlq.put({'event': 'exit', 'pid': os.getpid()})
-
-
while True:
-
data = cli_sock.recv(1024)
-
print data
-
if data.strip().lower() == "exit" or data.strip().lower() == "quit":
-
break
-
if not data:
-
break
-
cli_sock.send("[%s] %s" % (ctime(), data))
-
cli_sock.close()
-
ctlq.put({'event': 'exit', 'pid': os.getpid()})
-
-
def main_loop(host, port):
-
'''
-
基础服务01
-
'''
-
proc_pool = {}
-
ctlq = mp.Queue()
-
exit_flag = mp.Event()
-
-
signal(SIGINT, lambda x, y: exit_flag.set())
-
siginterrupt(SIGINT, False)
-
-
listen_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
listen_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
listen_sock.bind((host,port))
-
listen_sock.listen(128)
-
-
for i in range(NPROCES):
-
child = mp.Process(target=worker, args=(listen_sock, ctlq, exit_flag))
-
child.start()
-
proc_pool[child.pid] = child
-
print 'worker {} started'.format(child.pid)
-
-
while True:
-
print "parent join child process..."
-
item = ctlq.get()
-
if item['event'] == 'exit':
-
proc = proc_pool.pop(item['pid'])
-
proc.join()
-
print 'child {} stopped'.format(item['pid'])
-
-
# if child died, create new worker
-
child = mp.Process(target=worker, args=(listen_sock, ctlq, exit_flag))
-
child.start()
-
proc_pool[child.pid] = child
-
print 'worker {} started'.format(child.pid)
-
else:
-
print "It's impossible."
-
-
def main():
-
main_loop("0.0.0.0", 58001)
-
-
if __name__ == '__main__':
-
main()
阅读(2100) | 评论(0) | 转发(0) |