Tulip 的 《基本事件循环》第三篇 (共三篇)

这是很长的一篇 所以分成了几部分


18.5.1. Base Event Loop  基本事件循环

(...续前文,此为最后一篇)


8.5.1.8. Low-level socket operations 底层sockert操作

  • BaseEventLoop.sock_recv(socknbytes)

    Receive data from the socket. The return value is a bytes object representing the data received. The maximum amount of data to be received at once is specified by nbytes.

    This method is a coroutine.

    从socket接收数据。返回值是通过byte类型表示接收的数据的对象。每次接收数据的最大值通过nbytes指定。这个方法是一个coroutine。


    See also 参见 

    The socket.socket.recv() method. 


  • BaseEventLoop.sock_sendall(sockdata)

    Send data to the socket. The socket must be connected to a remote socket. This method continues to send data from data until either all data has been sent or an error occurs. None is returned on success. On error, an exception is raised, and there is no way to determine how much data, if any, was successfully processed by the receiving end of the connection.

    This method is a coroutine.

    发送数据到sokcet。socket必须连接到一个远程端口。这个方法不断从data 发送数据,知道所有数据发送完成或者出现错误。成功时返回None 。错误时,引发异常,并且无法确定多少数据被成功发送,如果这个方法是一个coroutine。


    See also 参见 

    The socket.socket.sendall() method.


  • BaseEventLoop.sock_connect(sockaddress)

    Connect to a remote socket at address.

    The address must be already resolved to avoid the trap of hanging the entire event loop when the address requires doing a DNS lookup. For example, it must be an IP address, not an hostname, for AF_INET and AF_INET6 address families. Use getaddrinfo() to resolve the hostname asynchronously.

    连接到一个address远程端口。

    address必须已经解析,防止陷入挂起到无限循环在DNS查找的陷阱中。例如,对于AF_INET 和AF_INET6它必须是一个IP地址,不能是一个主机名,使用getaddrinfo() 进行异步域名解析。


    This method is a coroutine.

    这个方法是一个coroutine


    See also 参见 

    The BaseEventLoop.create_connection() method, the open_connection() function and the socket.socket.connect()method.

    BaseEventLoop.create_connection()方法,open_connection() 函数和socket.socket.connect()方法。


  • BaseEventLoop.sock_accept(sock)

    Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address)where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.

    接受连接。这个socket必须是显露一个地址,并且在监听连接。返回值是一个(conn, address)对,其中的 conn是通过new 操作创建的,用于在这个连接发送和接受数据时的新socket对象,而address 是一个地址,用于暴露端口到其他的连接。


    This method is a coroutine.


    这个方法是一个coroutine


    See also 参见 

    The BaseEventLoop.create_server() method, the start_server() function and the socket.socket.accept() method.

    BaseEventLoop.create_server() 方法,start_server()函数和socket.socket.accept()方法。


18.5.1.9. Resolve host name 解析主机名

  • BaseEventLoop.getaddrinfo(hostport*family=0type=0proto=0flags=0)

    This method is a coroutine, similar to socket.getaddrinfo() function but non-blocking.

    这个方法是一个coroutine,类似于socket.getaddrinfo()函数,但不是肥猪晒的。


  • BaseEventLoop.getnameinfo(sockaddrflags=0)

    This method is a coroutine, similar to socket.getnameinfo() function but non-blocking.

    这个方法是一个coroutine,类似于socket.getnameinfo() 函数,但是不是非阻塞的。



18.5.1.10. Connect pipes  连接管道

  • BaseEventLoop.connect_read_pipe(protocol_factorypipe)

    Register read pipe in eventloop. Set the pipe to non-blocking mode.

    protocol_factory should instantiate object with Protocol interface. pipe is a file-like object. Return pair (transport, protocol), where transportsupports the ReadTransport interface.

    This method is a coroutine.

    在事件循环中注册一个读取管道。设置pipe为非阻塞模式。

    protocol_factory应该通过Protocol接口实例化对象。是一个类似文件的对象。返回(transport, protocol)对,其中transport支持ReadTransport接口。

    这个方法是一个coroutine。


  • BaseEventLoop.connect_write_pipe(protocol_factorypipe)

    Register write pipe in eventloop.

    protocol_factory should instantiate object with BaseProtocol interface. Pipe is file-like object already switched to nonblocking. Return pair (transport, protocol), where transport support WriteTransport interface.

    This method is a coroutine.

    在事件循环中注册一个写管道。

    protocol_factory应该使用BaseProtocol 接口进行实例化。管道是一个类似文件的对象,并且切换到非阻塞模式。返回 (transport, protocol)对,其中transport支持WriteTransport 接口。

   这个方法是一个coroutine。

See also 参见 

  The BaseEventLoop.subprocess_exec() and BaseEventLoop.subprocess_shell() methods.

 BaseEventLoop.subprocess_exec()BaseEventLoop.subprocess_shell()方法。 

   

18.5.1.11. UNIX signals UNIX信号

Availability: UNIX only.  仅适用于UNIX系统。

  • BaseEventLoop.add_signal_handler(signumcallback*args)

    Add a handler for a signal.

    Raise ValueError if the signal number is invalid or uncatchable. Raise RuntimeError if there is a problem setting up the handler.

    添加一个信号处理器。

    当信号编号不可用或者无法获取,产生ValueError 异常。

    当设置处理器出现问题时候,产生RuntimeError 异常。


  • BaseEventLoop.remove_signal_handler(sig)

    Remove a handler for a signal.

    Return True if a signal handler was removed, False if not.

    移除一个信号处理器。

    如果信号处理器被成功移除返回True否者返回False。


See also 参见 

  The signal module.  signal 模块。


18.5.1.12. Executor 执行器

Call a function in an Executor (pool of threads or pool of processes). By default, an event loop uses a thread pool executor (ThreadPoolExecutor).

调用在执行器(池或进程或进程池中)的函数,默认情况一个事件循环使用一个线程池执行器(ThreadPoolExecutor)。


  • BaseEventLoop.run_in_executor(executorcallback*args)

    Arrange for a callback to be called in the specified executor.

    安排一个回调,调用时在指定的执行器中执行。


    The executor argument should be an Executor instance. The default executor is used if executor is None.

    executor参数一个是一个Executor 实例。默认使用的executorNone


    This method is a coroutine.

    这个方法是一个coroutine



  • BaseEventLoop.set_default_executor(executor)

    Set the default executor used by run_in_executor().

    设置run_in_executor()使用的默认执行器。


18.5.1.13. Error Handling API  错误处理API

Allows to customize how exceptions are handled in the event loop.

允许自定义如何处理事件循环中的异常。


  • BaseEventLoop.set_exception_handler(handler)

    Set handler as the new event loop exception handler.

    handler 设置作为一个新的事件循环处理器。


    If handler is None, the default exception handler will be set.

    如果handler 为空,使用默认的异常处理器。


    If handler is a callable object, it should have a matching signature to (loop, context), where loop will be a reference to the active event loop, contextwill be a dict object (see call_exception_handler() documentation for details about context).

    如果handler 是一个回调对象,他需要有一个和 (loop, context)匹配的签名,其中的loop需要指向一个活动的事件循环,context是一个字典对象(参考call_exception_handler()文档获得context的详情)。


  • BaseEventLoop.default_exception_handler(context)

    Default exception handler.

    默认的异常处理器。

    This is called when an exception occurs and no exception handler is set, and can be called by a custom exception handler that wants to defer to the default behavior.

    在异常发生时并且没有设置异常处理器的时候被调用的,并且可以被一个延迟默认处理行为的自定义异常处理器调用。


    context parameter has the same meaning as in call_exception_handler().

    context参数和call_exception_handler()中的相同。


  • BaseEventLoop.call_exception_handler(context)

    Call the current event loop exception handler.

    调用当前事件循环异常控制器。


    context is a dict object containing the following keys (new keys may be introduced later):

    context 是一个字典对象,包含下面的键(新增的键稍后介绍):


    Note 注意 

    Note: this method should not be overloaded in subclassed event loops. For any custom exception handling, use set_exception_handler()method

    注意:这个方法不应该被子类的事件循环重载。对于一些自定义异常处理,使用set_exception_handler()方法。



    • ‘message’: Error message;  错误消息

    • ‘exception’ (optional): Exception object; 异常对象

    • ‘future’ (optional): asyncio.Future instance; asyncio.Future实例

    • ‘handle’ (optional): asyncio.Handle instance; asynci.Handle实例

    • ‘protocol’ (optional): Protocol instance;  Protocol实例

    • ‘transport’ (optional): Transport instance; Transport实例

    • ‘socket’ (optional): socket.socket instance. socket.socket实例


18.5.1.14. Debug mode  调试模式

  • BaseEventLoop.get_debug()

    Get the debug mode (bool) of the event loop.

    获得事件循环调试模式。

    The default value is True if the environment variable PYTHONASYNCIODEBUG is set to a non-empty string, False otherwise.

    默认值是True,如果PYTHONASYNCIODEBUG 环境变量设置为非空值,默认值为False。

    New in version 3.4.2. 在3.4.2版中新增。


  • BaseEventLoop.set_debug(enabled: bool)

    Set the debug mode of the event loop.

    设置事件循环调试模式。

    New in version 3.4.2. 在3.4.2版中新增。

See also 参见 

The debug mode of asyncio.


18.5.1.15. Server  服务器

  • class asyncio.Server

    Server listening on sockets. 服务器在socket上监听。

    Object created by the BaseEventLoop.create_server() method and the start_server() function. Don’t instantiate the class directly.

    通过BaseEventLoop.create_server()方法和start_server()函数创建对象,不要直接实例化类。



    • sockets

      List of socket.socket objects the server is listening to, or None if the server is closed.

      列出socket.socket的正在监听的对象,如果服务器被关闭,返回None。



    • wait_closed()

      Wait until the close() method completes.

      等待直到close() 方法完成。

      This method is a coroutine.

      此方法为coroutine


    • close()

      Stop serving: close listening sockets and set the sockets attribute to None.

      The sockets that represent existing incoming client connections are leaved open.

      The server is closed asynchonously, use the wait_closed() coroutine to wait until the server is closed.

      停止服务:管理并监听端口并设置socket属性为None。socket表示已经存在的传入的保持打开的客户端连接。使用wait_closed()协程,异步关闭务器。


18.5.1.16. Handle

  • class asyncio.Handle

    A callback wrapper object returned by BaseEventLoop.call_soon()BaseEventLoop.call_soon_threadsafe()BaseEventLoop.call_later(), and BaseEventLoop.call_at().

    一个回调用来包裹BaseEventLoop.call_soon()BaseEventLoop.call_soon_threadsafe()BaseEventLoop.call_later(), and BaseEventLoop.call_at()返回。



    • cancel()

      Cancel the call. 取消调用。


18.5.1.17. Event loop examples 事件循环实例

18.5.1.17.1. Hello World with call_soon()

Example using the BaseEventLoop.call_soon() method to schedule a callback. The callback displays "Hello World" and then stops the event loop:

使用BaseEventLoop.call_soon()方法安排一个回调示例,回调显示“Hello World”并且终止事件循环:

import asyncio

def hello_world(loop):
    print('Hello World')
    loop.stop()
    
loop = asyncio.get_event_loop()

# Schedule a call to hello_world()
loop.call_soon(hello_world, loop)

# Blocking call interrupted by loop.stop()
loop.run_forever()
loop.close()

See also

 

The Hello World coroutine example uses a coroutine.

18.5.1.17.2. Display the current date with call_later()

Example of callback displaying the current date every second. The callback uses the BaseEventLoop.call_later() method to reschedule itself during 5 seconds, and then stops the event loop:

每秒回调显示当前日期的实例,回调使用BaseEventLoop.call_later()方法,5秒钟后重新安排自己执行,停止事件循环。

import asyncioimport datetime
def display_date(end_time, loop):
    print(datetime.datetime.now())
    if (loop.time() + 1.0) < end_time:
        loop.call_later(1, display_date, end_time, loop)
    else:
        loop.stop()
loop = asyncio.get_event_loop()

# Schedule the first call to display_date()
end_time = loop.time() + 5.0
loop.call_soon(display_date, end_time, loop)

# Blocking call interrupted by loop.stop()
loop.run_forever()
loop.close()

See also

 

The coroutine displaying the current date example uses a coroutine.

18.5.1.17.3. Watch a file descriptor for read events

Wait until a file descriptor received some data using the BaseEventLoop.add_reader() method and then close the event loop:

等待直到接收到文件描述符使用BaseEventLoop.add_reader()接收数据,并关闭事件循环。

import asyncio
try:
    from socket import socketpair
except ImportError:
    from asyncio.windows_utils import socketpair
    
# Create a pair of connected file descriptors
rsock, wsock = socketpair()
loop = asyncio.get_event_loop()

def reader():
    data = rsock.recv(100)
    print("Received:", data.decode())
    
    # We are done: unregister the file descriptor
    loop.remove_reader(rsock)
    
    # Stop the event loop
    loop.stop()
    
# Register the file descriptor for read event
loop.add_reader(rsock, reader)

# Simulate the reception of data from the network
loop.call_soon(wsock.send, 'abc'.encode())

# Run the event loop
loop.run_forever()

# We are done, close sockets and the event loop
rsock.close()
wsock.close()
loop.close()

See also

 

The register an open socket to wait for data using a protocol example uses a low-level protocol created by theBaseEventLoop.create_connection() method.

The register an open socket to wait for data using streams example uses high-level streams created by the open_connection() function in a coroutine.

18.5.1.17.4. Set signal handlers for SIGINT and SIGTERM

Register handlers for signals SIGINT and SIGTERM using the BaseEventLoop.add_signal_handler() method:

使用BaseEventLoop.add_signal_handler()注册一个SIGINT 和SIGTERM 信号处理器。

import asyncio
import functools
import os
import signal

def ask_exit(signame):
    print("got signal %s: exit" % signame)
    loop.stop()
    
loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM'):
   loop.add_signal_handler(getattr(signal, signame),
       functools.partial(ask_exit, signame))
       
print("Event loop running forever, press CTRL+c to interrupt.")
print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid())

try:
  loop.run_forever()
finally:
  loop.close()

This example only works on UNIX.