多进程监听一个socket

进程组成:

  1. 可执行的程序(二进制或sh等可执行脚本)

  2. 数据

  3. 上下文环境

fork操作执行时:

  1. 给新进程分配新的内存空间、进程ID

  2. 复制父进程的数据、上下文环境到这块新的内存空间

  3. 程序则使用共享内存

这时子进程保存了父进程的文件描述符的所有副本,可以进程跟父进程一样的操作了。

对于监听一个socket来说,多个进程同时在accept处阻塞,当有一个连接进入,多个进程同时被唤醒,但之间只有一个进程能成功accept,而不会同时有多个进程能拿到该连接对象,操作系统保证了进程操作这个连接的安全性。

扩展:上述过程,多个进程同时被唤醒,去抢占accept到的资源,这个现象叫“惊群”,而根据网上资料,Linux 内核2.6以下,accept响应时只有一个进程accept成功,其他都失败,重新阻塞,也就是说所有监听进程同时被内核调度唤醒,这当然会耗费一定的系统资源。

而2.6以上,则已经不存在惊群现象了,但是由于开发者开发程序时使用了如epoll等异步通知技术,仍然会造成惊群,如有需要更高性能要求,或许参考nginx的实现方案

# -*- coding: utf-8-*-

import socket
import os

s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("", 6000))
s.listen(10)

gv = "x"

print "global value gv:", gv
print "parent pid:", os.getpid()

for i in xrange(3):
    pid = os.fork() # fork后, 父进程以及子进程的上下文环境都是执行到当前位置, 然后继续往下执行
    if pid == 0: # pid=0, 子进程获取到的状态
        conn, address = s.accept() # 在有连接进入之前, 所有进程都阻塞在这里
        conn.recv(1)
        conn.send('ok')
        
        print "child pid:", os.getpid()
    elif pid == 1:
        print "parent pid:", os.getpid()
    elif pid == -1: # pid=-1为系统异常状态
        print "error"
        
os.waitpid(pid, 0) # 主进程等待
print "parent pid:", os.getpid(), "end"







转载于:https://my.oschina.net/1123581321/blog/358126

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值