linux 多进程 缺陷ITeye - 娱乐之横扫全球

linux 多进程 缺陷ITeye

2019-01-10 15:51:27 | 作者: 耘涛 | 标签: 进程,封闭,一个 | 浏览: 485

 

fork有一些副效果,其中最显着的就是重复的文件描述符。比方,socket, 磁盘上的文件,终端(规范输入、输出,过错)或某些其他文件类目标。

 

由于一个进程的fork是一个精确的仿制,它承继了父进程的一切文件描述符和socket,所以就或许遇到这样一个状况,那就是父进程和子进程关于一个单一的长途主机,都有一个敞开的衔接.

 

这并不好,有几个原因,假如两个进程都视图经过socket通讯,成果就或许混杂。别的一点是,两个进程都要调用 close() ,衔接才干真正被封闭。因而,一些协议中,运用封闭socket作为某些操作完毕信号的状况会呈现问题。除非父进程和子进程都封闭了。

 

这个问题的解决办法是在fork之后,只需进程不必 socket的时分就立刻封闭它。

 

 

 

 

#!/usr/bin/env python

#!coding=utf-8

 

"""

forking 服务器

 

多进程服务器

"""

 

import socket ,traceback, os,sys

import time

 

def reap():

    print "in reap"

    """

    处理子进程

    """

    while 1:

        try:

            print "in reap ,pid=%s"%(getpid())

            result = os.waitpid(-1 , os.WNOHANG)  # -1 表明等候一切的子进程完毕,效果相当于调用wait ,WNOHANG表明不使父进程挂起,而当即回来

            print "000000000000000"

 

            if not result[0]:

                break

        except:

            break

 

        print "reaped child process %d" % result[0]

 

 

 

def getpid():

    return os.getpid()

 

host=

port=9002

 

s =socket.socket(socket.AF_INET, socket.SOCK_STREAM)

 

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

 

s.bind((host, port))

 

s.listen(1)

 

 

print "parent at %d listening for connection" % getpid()

 

if __name__ == "__main__":

    while 1:

        try:

            print "accept , pid= %s"%(getpid())

            clientsock , clientaddr = s.accept()

            print "start accpet"

        except KeyboardInterrupt:

            raise

        except:

            traceback.print_exc()

            continue

 

        #reap()

 

        pid = os.fork()

        print "*****************"

 

        if pid:

            #子父进程中

            #this is the parent process .close the childs socket

            print "in parent socket"+str(clientsock)

            print "in parent port=%s"%str(port)

            print "in parent s=%s"%str(s)

 

            """

            这儿为什么要封闭clientsock呢,这儿解说(this is the parent process .close the childs socket)

            封闭的是子线程的socket,我觉得是写错了,

            应该封闭的是父进程的client的socket衔接,由于这儿是在父进程里边,这儿为什么要封闭呢,

            由于多进程是, 子进程会仿制父进程的数据,那么这样clientsocket,就会存在2次饮用(父进程一个,

            子进程一个) ,假如每创立一次子进程都添加一次引证的话,这样就会耗费体系的资源,所以这儿应该封闭

            """

            clientsock.close()

            #s.close()

            print "in parent socket"+str(clientsock)

            continue

        else:

            #在子进程中

            #from here on . this is child

            #clientsock.close()

            print "in child socket"+str(clientsock)

            print "in child port=%s"%str(port)

            print "in child s=%s"%str(s)

 

            """

            子进程里边也有s, 父进程也有s,假如这时分,客户端有衔接的话,就有或许呈现紊乱的状况,所以这儿挑选封闭

            子进程的s

            """

            s.close()

 

 

 

        #process the connection

        try:

            print "child from %s being handled bu pid %d"%\

            (clientsock.getpeername(), os.getpid())

 

        #不断的循环接纳数据

            while 1:

                data = clientsock.recv(4096)

                print str(data) + " , pid = %s"%(getpid())

                if not len(data):

                    break

                clientsock.sendall(data)

        except(KeyboardInterrupt, SystemExit):

            raise

        except:

            traceback.print_exc()

 

 

    #close the connection

        try:

            print "断开衔接 ,pid=%s"%(getpid())

            clientsock.close()

        except KeyboardInterrupt:

            raise

        except:

            traceback.print_exc()

 

        print "进程完毕,pid=%s"%(getpid())

        sys.exit(0)

 

 

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表娱乐之横扫全球立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章