利用multiprocessing做进程间通信

来源:互联网 发布:数据统计图表分析 编辑:程序博客网 时间:2024/06/13 15:13

 

3.3 multiprocess 创建进程

         能批量产生进程。

         采用Process类创建进程。用于创建代码可控的进程,非脚本执行进程和系统命令进程。

3.3.1 建立两个子进程的Queue通信

         创建两个队列,分别作为两个进程的读写管道。

q1 = Queue()q2 = Queue()consoleP = Process(target=script_runner.startConsole args=(q2, q1,))httpP = Process(target=httpserver.startServer, args=(q1, q2,))consoleP.start()time.sleep(3)httpP.start()

script_runner.startConsole :进程入口函数

httpserver.startServer:进程入口函数

 

         如上面代码,可以定义q1队列为:进程consoleP写数据,进程httpP读数据;q2队列为:进程consoleP读数据,进程httpP写数据。

         一个进程崩溃,可以根据持有的队列进行恢复。此处存在3个进程,任何一个进程崩溃,均不会影响其他进程。可以设定异常,验证。

         例如异常代码:str ="" + 1

         缺陷:如果一方启动的进程是httpserver,例如SimpleHttpServer,有自己的进程恢复机制,则无法恢复队列通信。

         此时考虑用用pythonConnect类对象处理子进程之间的通信,也适合完全无关的两个进程间的通信,如章节3.3.2。

 

3.3.2 完全独立进程间的通信

         两个完全独立的进程,一般采用命名Pipe或者Socket通信,在windows下,python没有实现命名pipe。另外,python实现了更高层级的通信机制,Listener和Client机制。

         Listener服务端:

address = ("localhost", 8000)listener = Listener(address, authkey="password")print "Accept"conn = listener.accept()print conn.recv()

 

         Client客户端:

address = ("localhost", 8000) conn = Client(address,authkey="password")time.sleep(5)dict = {"action":"testbase"}conn.send(json.dumps(dict))

        

         如果两个进程均要主动发送请求,则考虑建立两个通信链路。如下面实现类:

class HttpConsoleBinder():    HttpServer_Port = 6000    Console_Port = HttpServer_Port + 1    def __init__(self):        self.httpAddress = ("localhost", HttpConsoleBinder.HttpServer_Port)        self.consoleAddress = ("localhost", HttpConsoleBinder.Console_Port)    def initHttpListener(self):        self.httpListener = Listener(self.httpAddress, authkey="password")    def initConsoleListener(self):        self.consoleListener = Listener(self.consoleAddress, authkey="password")    def sendToHttp(self,action, data):        self.httpClient = Client(self.httpAddress, authkey="password")        data["action"] = action        jsonStr = json.dumps(data)        try:            self.httpClient.send(jsonStr)        except Exception,e:            print e        finally:            self.httpClient.close()    def sendToConsole(self, action, data):        self.consoleClient = Client(self.consoleAddress, authkey="password")        data["action"] = action        jsonStr = json.dumps(data)        try:            self.consoleClient.send(jsonStr)        except Exception,e:            print e        finally:            self.consoleClient.close()    def acceptHttp(self):        conn = self.consoleListener.accept()        data = conn.recv()        dataDict = json.loads(data)        action = dataDict["action"]        conn.close()        return action,dataDict    def acceptConsole(self):        conn = self.httpListener.accept()        data = conn.recv()        dataDict = json.loads(data)        action = dataDict["action"]        conn.close()        return action,dataDict

 

         上面的类针对两个终端:Http和Console

         双向测试代码如下:

def testP1():    binder = HttpConsoleBinder()    binder.initConsoleListener()    print "Wait http"    action,data = binder.acceptHttp()    print "testP1,action:",action,";data:",data    print "Send to http"    binder.sendToHttp("test", {"keyP1": "valueP1"})def testP2():    binder = HttpConsoleBinder()    binder.initHttpListener()    print "Send to console"    binder.sendToConsole("test", {"keyP2":"valueP2"})    print "Wait console"    action,data = binder.acceptConsole()    print "testP2,action:",action,";data:",data
 
if __name__ == "__main__":    q1 = Queue()    q2 = Queue()    p1 = Process(target=testP1, args=())    p1.start()    time.sleep(3)    p2 = Process(target=testP2, args=())    p2.start()

可以看到打印如下:

Wait http

Send to console

Wait console

testP1,action: test ;data: {u'action':u'test', u'keyP2': u'valueP2'}

Send to http

testP2,action: test ;data: {u'action':u'test', u'keyP1': u'valueP1'}

原创粉丝点击