fbpx
维基百科

異步I/O

异步I/O是计算机操作系统对输入输出的一种处理方式:发起I/O请求的线程不等I/O操作完成,就继续执行随后的代码,I/O结果用其他方式通知发起I/O请求的程序。与异步I/O相对的是更为常见的“同步(阻塞)I/O”:发起I/O请求的线程不从正在调用的I/O操作函数返回(即被阻塞),直至I/O操作完成。

类Unix操作系统与POSIX 编辑

POSIX提供下述API函数:

阻塞 非阻塞
同步 write, read write, read + poll / select
异步 - aio_write, aio_read
  • aio[1]
  • io_uring (Linux 5.1以後支援)[2]

Windows操作系统的异步I/O 编辑

Windows提供多种异步I/O(也称重叠I/O)方式:[3]

设备内核对象 编辑

I/O设备在操作系统内核中表示为内核对象,因此具有可等待(waitable)内核对象状态。例如:文件句柄,线程句柄等等。对于文件内核对象,当一个异步I/O完成后,该文件句柄被置为触发态。使用这种方式获取异步I/O完成的通知,缺点是如果在一个文件内核对象上同时有多个异步I/O操作,只通过文件句柄的触发无法辨识哪个异步I/O操作完成了。

例子:

HANDLE hFile = CreateFileW(L"d:\\a.txt", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, 0); //设置异步IO的标志FILE_FLAG_OVERLAPPED char buffer[10] = {"abcd"}; OVERLAPPED ol = { 0 };//用0初始化OVERLAPPED的结构 ol.Offset = 2;/从文件的第三个字节开始IO BOOL rt = WriteFile(hFile, buffer, 5, NULL, &ol);//发起一个异步写操作 //SetFileCompletionNotificationModes(hFile, FILE_SKIP_SET_EVENT_ON_HANDLE);//如此设置则文件内核对象就不会被触发 if (rt == FALSE && GetLastError() == ERROR_IO_PENDING)//检查异步IO是否完成  { WaitForSingleObject(hFile, INFINITE);//等待设备内核对象(文件)被触发。 } CloseHandle(hFile); 

GetOverlappedResult函数 编辑

也可以使用Windows API函数GetOverlappedResult直接阻塞/非阻塞等待指定的异步I/O操作是否完成。[4]该函数检查OVERLAPPED结构中的Internal成员的值是否为STATUS_PENDING来判断异步I/O是否完成。

异步I/O操作的完成通知用事件内核对象 编辑

在异步I/O操作的read/write函数调用中给出的OVERLAPPED类型的参数中,可以指定一个内核事件对象。这个异步I/O操作完成时,这个内核事件对象会被触发。从而,等待在这个事件对象上的程序就会知道这个异步I/O操作完成。

例子:

HANDLE hFile = CreateFileW(L"d:\\a.txt", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, 0); //设置异步IO的标志FILE_FLAG_OVERLAPPED char buffer[10] = {"abcd"}; OVERLAPPED ol = { 0 };//用0初始化OVERLAPPED的结构 ol.Offset = 2;/从文件的第三个字节开始IO HANDLE hEvent = CreateEvent(0, FALSE, FALSE, NULL);  ol.hEvent = hEvent;//传递一个事件对象。  BOOL rt = WriteFile(hFile, buffer, 5, NULL, &ol);//发起一个异步写操作  if (rt == FALSE && GetLastError() == ERROR_IO_PENDING)//检查异步IO是否完成  { WaitForSingleObject(ol.hEvent, INFINITE);//等待设备内核对象(文件)被触发。 } CloseHandle(hEvent);  CloseHandle(hFile); 

可唤醒I/O 编辑

异步可唤醒I/O操作通过ReadFileEx/WriteFileEx函数指出完成过程回调函数。回调函数在该线程的可唤醒等待(alertable wait)中被执行。

完成端口 编辑

使用CreateIoCompletionPort函数创建一个完成端口。然后把文件句柄绑定到这个完成端口(通过CreateIoCompletionPort函数)。这个文件句柄上的异步I/O操作完成时,会自动向这个完成完成端口发通知。线程通过GetQueuedCompletionStatus函数等待这个完成端口上的完成通知,然后从GetQueuedCompletionStatus的调用返回处恢复线程执行。

线程池I/O完成对象 编辑

使用CreateThreadpoolIo函数创建一个I/O完成对象,绑定了要执行异步I/O操作的文件句柄与待执行的回调函数。通过StartThreadpoolIo函数开始I/O完成对象的工作。每当绑定的文件句柄上的异步I/O操作完成,自动调用线程池上的线程执行指定的回调函数。

例子:

VOID CALLBACK OverlappedCompletionRoutine(PTP_CALLBACK_INSTANCE pInstance,      PVOID pvContext,      PVOID pOverlapped,      ULONG IoResult,      ULONG_PTR NumberOfBytesTransferred,      PTP_IO pIo)  {   printf("OverlappedCompletionRoutine, transferred: %d bytes\n", NumberOfBytesTransferred);  }  HANDLE hFile = CreateFileW(L"d:\\a.txt", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, 0); //设置异步IO的标志FILE_FLAG_OVERLAPPED PTP_IO pio = CreateThreadpoolIo(hFile, OverlappedCompletionRoutine, NULL, NULL);//将设备对象和线程池的IO完成端口关联起来。  StartThreadpoolIo(pio); char buffer[10] = {"abcd"}; OVERLAPPED ol = { 0 };//用0初始化OVERLAPPED的结构 ol.Offset = 2;/从文件的第三个字节开始IO  BOOL rt = WriteFile(hFile, buffer, 5, NULL, &ol);//发起一个异步写操作  if(rt==FALSE && GetLastError()==ERROR_IO_PENDING)) {   ::Sleep(4000);   //do somethings...  } else {  CancelThreadpoolIo(pio);  } WaitForThreadpoolIoCallbacks(pio,false); CloseHandle(hFile);  CloseThreadpoolIo(pio);//关闭线程池io完成对象 

参见 编辑

参考文献 编辑

  1. ^ aio - POSIX asynchronous I/O overview. Linux manual page. [2020-08-25]. (原始内容于2020-04-12). 
  2. ^ Ringing in a new asynchronous I/O API. LWN.net. [2020-08-25]. (原始内容于2020-07-09). 
  3. ^ Description from .NET Framework Developer's Guide. [2017-12-16]. (原始内容于2018-06-14). 
  4. ^ MSDN:GetOverlappedResult function. [2017-12-16]. (原始内容于2017-12-16). 

外部链接 编辑

  • ; a survey of asynchronous I/O methods with emphasis on scaling – by Dan Kegel
  • Article "Boost application performance using asynchronous I/O (页面存档备份,存于互联网档案馆)" by M. Tim Jones
  • Article "Lazy Asynchronous I/O For Event-Driven Servers (页面存档备份,存于互联网档案馆)" by Willy Zwaenepoel, Khaled Elmeleegy, Anupam Chanda and Alan L. Cox
  • Perform I/O Operations in Parallel (页面存档备份,存于互联网档案馆
  • Description from POSIX standard (页面存档备份,存于互联网档案馆
  • by Mark Russinovich
  • Asynchronous I/O and The Asynchronous Disk I/O Explorer (页面存档备份,存于互联网档案馆
  • I/O::AI/O is a Perl module offering an asynchronous interface for most I/O operations (页面存档备份,存于互联网档案馆

異步i, 异步i, o是计算机操作系统对输入输出的一种处理方式, 发起i, o请求的线程不等i, o操作完成, 就继续执行随后的代码, o结果用其他方式通知发起i, o请求的程序, 与异步i, o相对的是更为常见的, 同步, 阻塞, 发起i, o请求的线程不从正在调用的i, o操作函数返回, 即被阻塞, 直至i, o操作完成, 目录, 类unix操作系统与posix, windows操作系统的异步i, 设备内核对象, getoverlappedresult函数, 异步i, o操作的完成通知用事件内核对象, 可唤醒i. 异步I O是计算机操作系统对输入输出的一种处理方式 发起I O请求的线程不等I O操作完成 就继续执行随后的代码 I O结果用其他方式通知发起I O请求的程序 与异步I O相对的是更为常见的 同步 阻塞 I O 发起I O请求的线程不从正在调用的I O操作函数返回 即被阻塞 直至I O操作完成 目录 1 类Unix操作系统与POSIX 2 Windows操作系统的异步I O 2 1 设备内核对象 2 2 GetOverlappedResult函数 2 3 异步I O操作的完成通知用事件内核对象 2 4 可唤醒I O 2 5 完成端口 2 6 线程池I O完成对象 3 参见 4 参考文献 5 外部链接类Unix操作系统与POSIX 编辑POSIX提供下述API函数 阻塞 非阻塞 同步 write read write read poll select 异步 aio write aio read aio 1 io uring Linux 5 1以後支援 2 Windows操作系统的异步I O 编辑Windows提供多种异步I O 也称重叠I O 方式 3 设备内核对象 编辑 I O设备在操作系统内核中表示为内核对象 因此具有可等待 waitable 内核对象状态 例如 文件句柄 线程句柄等等 对于文件内核对象 当一个异步I O完成后 该文件句柄被置为触发态 使用这种方式获取异步I O完成的通知 缺点是如果在一个文件内核对象上同时有多个异步I O操作 只通过文件句柄的触发无法辨识哪个异步I O操作完成了 例子 HANDLE hFile CreateFileW L d a txt GENERIC WRITE 0 0 CREATE ALWAYS FILE FLAG OVERLAPPED 0 设置异步IO的标志FILE FLAG OVERLAPPED char buffer 10 abcd OVERLAPPED ol 0 用0初始化OVERLAPPED的结构 ol Offset 2 从文件的第三个字节开始IO BOOL rt WriteFile hFile buffer 5 NULL amp ol 发起一个异步写操作 SetFileCompletionNotificationModes hFile FILE SKIP SET EVENT ON HANDLE 如此设置则文件内核对象就不会被触发 if rt FALSE amp amp GetLastError ERROR IO PENDING 检查异步IO是否完成 WaitForSingleObject hFile INFINITE 等待设备内核对象 文件 被触发 CloseHandle hFile GetOverlappedResult函数 编辑 也可以使用Windows API函数GetOverlappedResult直接阻塞 非阻塞等待指定的异步I O操作是否完成 4 该函数检查OVERLAPPED结构中的Internal成员的值是否为STATUS PENDING来判断异步I O是否完成 异步I O操作的完成通知用事件内核对象 编辑 在异步I O操作的read write函数调用中给出的OVERLAPPED类型的参数中 可以指定一个内核事件对象 这个异步I O操作完成时 这个内核事件对象会被触发 从而 等待在这个事件对象上的程序就会知道这个异步I O操作完成 例子 HANDLE hFile CreateFileW L d a txt GENERIC WRITE 0 0 CREATE ALWAYS FILE FLAG OVERLAPPED 0 设置异步IO的标志FILE FLAG OVERLAPPED char buffer 10 abcd OVERLAPPED ol 0 用0初始化OVERLAPPED的结构 ol Offset 2 从文件的第三个字节开始IO HANDLE hEvent CreateEvent 0 FALSE FALSE NULL ol hEvent hEvent 传递一个事件对象 BOOL rt WriteFile hFile buffer 5 NULL amp ol 发起一个异步写操作 if rt FALSE amp amp GetLastError ERROR IO PENDING 检查异步IO是否完成 WaitForSingleObject ol hEvent INFINITE 等待设备内核对象 文件 被触发 CloseHandle hEvent CloseHandle hFile 可唤醒I O 编辑 异步可唤醒I O操作通过ReadFileEx WriteFileEx函数指出完成过程回调函数 回调函数在该线程的可唤醒等待 alertable wait 中被执行 完成端口 编辑 使用CreateIoCompletionPort函数创建一个完成端口 然后把文件句柄绑定到这个完成端口 通过CreateIoCompletionPort函数 这个文件句柄上的异步I O操作完成时 会自动向这个完成完成端口发通知 线程通过GetQueuedCompletionStatus函数等待这个完成端口上的完成通知 然后从GetQueuedCompletionStatus的调用返回处恢复线程执行 线程池I O完成对象 编辑 使用CreateThreadpoolIo函数创建一个I O完成对象 绑定了要执行异步I O操作的文件句柄与待执行的回调函数 通过StartThreadpoolIo函数开始I O完成对象的工作 每当绑定的文件句柄上的异步I O操作完成 自动调用线程池上的线程执行指定的回调函数 例子 VOID CALLBACK OverlappedCompletionRoutine PTP CALLBACK INSTANCE pInstance PVOID pvContext PVOID pOverlapped ULONG IoResult ULONG PTR NumberOfBytesTransferred PTP IO pIo printf OverlappedCompletionRoutine transferred d bytes n NumberOfBytesTransferred HANDLE hFile CreateFileW L d a txt GENERIC WRITE 0 0 CREATE ALWAYS FILE FLAG OVERLAPPED 0 设置异步IO的标志FILE FLAG OVERLAPPED PTP IO pio CreateThreadpoolIo hFile OverlappedCompletionRoutine NULL NULL 将设备对象和线程池的IO完成端口关联起来 StartThreadpoolIo pio char buffer 10 abcd OVERLAPPED ol 0 用0初始化OVERLAPPED的结构 ol Offset 2 从文件的第三个字节开始IO BOOL rt WriteFile hFile buffer 5 NULL amp ol 发起一个异步写操作 if rt FALSE amp amp GetLastError ERROR IO PENDING Sleep 4000 do somethings else CancelThreadpoolIo pio WaitForThreadpoolIoCallbacks pio false CloseHandle hFile CloseThreadpoolIo pio 关闭线程池io完成对象参见 编辑IOCP参考文献 编辑 aio POSIX asynchronous I O overview Linux manual page 2020 08 25 原始内容存档于2020 04 12 Ringing in a new asynchronous I O API LWN net 2020 08 25 原始内容存档于2020 07 09 Description from NET Framework Developer s Guide 2017 12 16 原始内容存档于2018 06 14 MSDN GetOverlappedResult function 2017 12 16 原始内容存档于2017 12 16 外部链接 编辑The C10K Problem a survey of asynchronous I O methods with emphasis on scaling by Dan Kegel Article Boost application performance using asynchronous I O 页面存档备份 存于互联网档案馆 by M Tim Jones Article Lazy Asynchronous I O For Event Driven Servers 页面存档备份 存于互联网档案馆 by Willy Zwaenepoel Khaled Elmeleegy Anupam Chanda and Alan L Cox Perform I O Operations in Parallel 页面存档备份 存于互联网档案馆 Description from POSIX standard 页面存档备份 存于互联网档案馆 Inside I O Completion Ports by Mark Russinovich Asynchronous I O and The Asynchronous Disk I O Explorer 页面存档备份 存于互联网档案馆 I O AI O is a Perl module offering an asynchronous interface for most I O operations 页面存档备份 存于互联网档案馆 ACE Proactor 取自 https zh wikipedia org w index php title 異步I O amp oldid 74819487, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。