【问题标题】:How to share socket with asyncio in Python3?如何在 Python3 中与 asyncio 共享套接字?
【发布时间】:2017-08-19 13:29:09
【问题描述】:

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

data_received()回调中有一个heavy_jobs()函数,会占用大量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 中做同样的事情呢?

【问题讨论】:

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


    【解决方案1】:

    目前 asyncio 不支持在事件循环运行时分叉 (https://bugs.python.org/issue21998)。您必须分叉然后创建循环。一个简单的 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,然后启动客户端(上面的代码)。

    如果您还想编写服务器,只需将connect 更改为socket.bindsocket.listen,当然还有asyncio.create_server

    【讨论】:

    • 谢谢,真的很有帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多