如何在Python3中与asyncio共享套接字?

时间:2017-08-19 13:29:10

标签: python python-3.x sockets python-asyncio

我需要使用asyncioos.fork()方法在子进程之间共享套接字。

heavy_jobs()回调中有一个data_received()函数,会占用大量的CPU时间。

import asyncio

class EchoClientProtocol(asyncio.Protocol):
    def __init__(self, message, loop):
        self.message = message
        self.loop = loop

    def data_received(self, data):
        heavy_jobs()

loop = asyncio.get_event_loop()
message = 'Hello World!'
coro = loop.create_connection(lambda: EchoClientProtocol(message, loop),
                              '127.0.0.1', 8000)
loop.run_until_complete(coro)
loop.run_forever()
loop.close()

在传统方法中,我们可以使用fork()在子进程和父进程之间共享套接字:

bind(...);
listen(...);
pid = fork();

那么,我怎样才能在asyncio中做同样的事情?

1 个答案:

答案 0 :(得分:0)

目前asyncio在事件循环运行时不支持fork(https://bugs.python.org/issue21998)。你必须fork然后创建循环。一个简单的EchoClient,有两个进程:

import asyncio
import os
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('127.0.0.1', 7777))
pid = os.fork()

class EchoClientProtocol(asyncio.Protocol):
    def __init__(self, message, loop):
        self.message = message
        self.loop = loop

    def data_received(self, data):
        print('Received in %s' % pid)

loop = asyncio.get_event_loop()
message = 'Hello World!'
coro = loop.create_connection(lambda: EchoClientProtocol(message, loop), sock=sock)
loop.run_until_complete(coro)
loop.run_forever()
loop.close()

简单的测试 - 运行nc -k -l 7777,然后启动客户端(上面的代码)。

如果您还想编写服务器,只需使用connectsocket.bind更改socket.listen,当然asyncio.create_server