python多进程网络服务器

10 篇文章 0 订阅
3 篇文章 0 订阅

最近看Nginx有些收获,于是想用python语言来实现一个简易的网络服务器模型:一个主进程和3个子进程,主进程只负责创建侦听的socket,并创建子进程然后等待子进程退出,而真正的工作全部交给子进程来做,包括接收新的连接请求以及发送。这里没有使用锁,而只是用了时间戳来简单模拟避免‘惊群’现象的发生。这里也省去了进程之间通信以及信号处理等工作。

具体代码如下:


#encoding=utf-8

import os
import sys
import socket
import select
import time

NUM = 3

def process_req(serversocket, pos):
    pid = os.getpid()
    epoll = select.epoll()

    held = 0
    connections = {}
    requests = {}
    responses = {}

    while True:
        minutes = time.localtime()[4]
        if minutes % NUM == pos:
            if held==0:
                epoll.register(serversocket.fileno(), select.EPOLLIN)
                held = 1
        elif held == 1:
            epoll.unregister(serversocket.fileno())
            held = 0

        events = epoll.poll(1)
        for fileno, event in events:
            if fileno == serversocket.fileno():
                connection, address = serversocket.accept()
                connection.setblocking(0)
                epoll.register(connection.fileno(), select.EPOLLIN)

                connections[connection.fileno()] = connection
                requests[connection.fileno()] = ''
                responses[connection.fileno()] = ''
                print 'accept socket, pid = %d, fileno= %d' % (pid, fileno)

            elif event & select.EPOLLIN:
                requests[fileno] += connections[fileno].recv(1024)
                if requests[fileno].find('END') >= 0:
                    responses[fileno] = requests[fileno]
                    epoll.modify(fileno, select.EPOLLOUT)
                    print requests[fileno]
            elif event & select.EPOLLOUT:
                byteswritten = connections[fileno].send(responses[fileno])
                responses[fileno] = responses[fileno][byteswritten:]
                if len(responses[fileno]) == 0:
                    epoll.modify(fileno, 0)
                    connections[fileno].shutdown(socket.SHUT_RDWR)

            elif event & select.EPOLLHUP:
                epoll.unregister(fileno)
                connections[fileno].close()
                del connections[fileno]

    epoll.unregister(serversocket.fileno())
    epoll.close()
    serversocket.close()



if __name__ == "__main__":

    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    serversocket.bind(('0.0.0.0', 8888))
    serversocket.listen(1)
    serversocket.setblocking(0)

    pid_arr = []

    for i in range(0, NUM):
        pid = os.fork()
        if pid == 0:
            print 'in child: ', os.getpid()
            process_req(serversocket, i)
            sys.exit()
        else:
            pid_arr.append(pid)

    serversocket.close()

    for pid in pid_arr:
        os.waitpid(pid, 0)

    print '~~~ finish ~~~'


 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值