微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Asynchronous I/O 和 Overlapped I/O

Asynchronous I/O

Synchronous I/O 会阻塞以等待 I/O 操作完成,I/O 操作涉及数据在硬件上的移动,较内存上的电流改变,效率上低数个数量级。在等待 I/O 操作完成期间,处理器处于空闲状态。为了充分压榨处理器性能,在等待 I/O 操作完成期间,处理器可以处理与此次 I/O 无关的操作。这就是 Asynchronous I/O 的作用,Asynchronous I/O 不会阻塞,程序可以继续执行,当 I/O 操作完成后,OS 通知程序该 I/O 操作完成(基于设备状态轮询或者硬件中断)。

Asynchronous I/O 被用于提升效率,在某些情况下,也能提升吞吐量。然而,它在时延方面有消极的影响,有时吞吐量方面也是如此。

Forms

Blocking Non-blocking Asynchronous
API write, read write, read + poll/select aio_write, aio_read

所有形式的异步 I/O 都涉及资源冲突和相关的问题。

Process

Select(/poll)

select loop 使用 select 系统调用进行休眠,等待文件描述符上的情况发生,超时发生,或接收到一个信号(比如,当子进程死亡)。通过检查 select 的返回参数,循环找出哪个文件描述符已经发生了改变并执行相应的代码。通常,为了易于使用,select loop 被实现为 event loop,或许会使用 callback functions;非常适用于 event-driven programming。

Signals

BSD 和 POSIX Unix 可用。I/O 被异步发起,当它完成时,signal(interrupt) 被生成

Light-weight processes or threads

Light-weight processes(LWPs) 或 threads 在很多现代 Unixs 中可用。如同 process 方法,但是没有阻碍流之间合作的数据隔离。缺少隔离引入了它自己的问题,通常需要内核提供的同步机制和线程安全库。每个 LWP 或线程本身使用传统的阻塞同步 I/O。必须分离的线程栈可能妨碍使用非常大量线程的大规模实现。

Completion queues/ports

I/O 请求是异步发起的,但是完成的通知是通过同步队列机制,以 I/O 完成的的顺序提供的。通常与主进程(event-driven programming) 的状态机结构相关联, 这与不使用异步 I/O 或者使用其他形式的异步 I/O 没有一点相似之处,导致代码很难重用。不需要额外的同步机制或者线程安全库,文本(code)流和时间(event)流也不分离。

Implementation

绝大部分的通用目的的计算硬件完全依赖于两种异步 I/O实现方法:polling 和 interrupts。通常两种方法一起使用,

Examples

  1. 阻塞,同步:
device = IO.open()
data = device.read() # thread will be blocked until there is data in the device
print(data)
  1. 阻塞和非阻塞,同步
device = IO.open()
ready = False
while not ready:
    print("There is no data to read!")
    ready = IO.poll(device, IO.INPUT, 5) # returns control if 5 seconds have elapsed or there is data to read (INPUT)
data = device.read()
print(data)
  1. 非阻塞,异步
ios = IO.IOService()
device = IO.open(ios)

def inputHandler(data, err):
    "Input data handler"
    if not err:
        print(data)

device.readSome(inputHandler)
ios.loop() # wait till all operations have been completed and call all appropriate handlers

Async/await:

ios = IO.IOService()
device = IO.open(ios)

async def task():
    try: 
        data = await device.readSome()
        print(data)
    except:
        pass

ios.addTask(task)
ios.loop() # wait till all operations have been completed and call all appropriate handlers

Reactor pattern:

device = IO.open()
reactor = IO.Reactor()

def inputHandler(data):
    "Input data handler"
    print(data)
    reactor.stop()

reactor.addHandler(inputHandler, device, IO.INPUT)
reactor.run() # run reactor, which handles events and calls appropriate handlers

Overlapped I/O

Overlapped I/O 是 Windows API 中对于 asynchronous I/O 的名字。

原文地址:https://www.jb51.cc/wenti/3284231.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐