简体   繁体   English

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

[英]How to share socket with asyncio in Python3?

I need to use asyncio with os.fork() method for sharing socket between subprocess. 我需要使用asyncioos.fork()方法用于子之间共享插槽。

There is a heavy_jobs() function in data_received() callback, which will occupy a lot of CPU time. 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()

In traditional method, we could use fork() to share socket between subprocess and parent: 在传统方法中,我们可以使用fork()在子进程和父进程之间共享套接字:

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

So, how could I do the same thing in asyncio ? 所以,我怎么能在asyncio做同样的事情?

Currently asyncio does not support fork while the event loop is running ( https://bugs.python.org/issue21998 ). 当前,当事件循环运行时,asyncio不支持fork( https://bugs.python.org/issue21998 )。 You must fork and then create the loop. 您必须先分叉,然后创建循环。 A simple EchoClient with two processes: 一个简单的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()

And simple test - run nc -k -l 7777 , then start the client (code above). 和简单的测试-运行nc -k -l 7777 ,然后启动客户端(上面的代码)。

If you also want to write a server, just change connect with socket.bind and socket.listen and of course asyncio.create_server 如果您还想编写服务器,只需更改与socket.bindsocket.listen connect ,当然asyncio.create_server

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM