非同步 IO 是計算機作業系統對輸入輸出的一種處理方式：發起 IO 請求的執行緒不等 IO 操作完成，就繼續執行隨後的程式碼，IO 結果用其他方式通知發起 IO 請求的程式。與非同步 IO 相對的是更為常見的 同步（阻塞）IO：發起 IO 請求的執行緒不從正在呼叫的 IO 操作函式返回（即被阻塞），直至 IO 操作完成。 類 Unix 作業系統與 POSIX POSIX 提供下述 API 函式： 阻塞 非阻塞 同步 write read write read poll select 非同步 aio_write aio_read aio io_uring Linux 51 以後支援 Windows 作業系統的非同步 IO Windows 提供多種非同步 IO（也稱重疊 IO）方式： 裝置核心物件 IO 裝置在作業系統核心中表示為核心物件，因此具有可等待（waitable）核心物件狀態。例如：檔案控制代碼，執行緒控制代碼等等。對於檔案核心物件，當一個非同步 IO 完成後，該檔案控制代碼被置為觸發態。使用這種方式獲取非同步 IO 完成的通知，缺點是如果在一個檔案核心物件上同時有多個非同步 IO 操作，只通過檔案控制代碼的觸發無法辨識哪個非同步 IO 操作完成了。 例子： HANDLE hFile CreateFileW Ldatxt GENERIC_WRITE 0 0 CREATE_ALWAYS FILE_FLAG_OVERLAPPED 0 設定非同步 IO 的標誌 FILE_FLAG_OVERLAPPED char buffer 10 abcd OVERLAPPED ol 0 用 0 初始化 OVERLAPPED 的結構 olOffset 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 直接阻塞 非阻塞等待指定的非同步 IO 操作是否完成。該函式檢查 OVERLAPPED 結構中的 Internal 成員的值是否為 STATUS_PENDING 來判斷非同步 IO 是否完成。 非同步 IO 操作的完成通知用事件核心物件 在非同步 IO 操作的 readwrite 函式呼叫中給出的 OVERLAPPED 型別的引數中，可以指定一個核心事件物件。這個非同步 IO 操作完成時，這個核心事件物件會被觸發。從而，等待在這個事件物件上的程式就會知道這個非同步 IO 操作完成。 例子： HANDLE hFile CreateFileW Ldatxt GENERIC_WRITE 0 0 CREATE_ALWAYS FILE_FLAG_OVERLAPPED 0 設定非同步 IO 的標誌 FILE_FLAG_OVERLAPPED char buffer 10 abcd OVERLAPPED ol 0 用 0 初始化 OVERLAPPED 的結構 olOffset 2 從檔案的第三個位元組開始 IO HANDLE hEvent CreateEvent 0 FALSE FALSE NULL olhEvent hEvent 傳遞一個事件物件。 BOOL rt WriteFile hFile buffer 5 NULL ol 發起一個非同步寫操作 if rt FALSE GetLastError ERROR_IO_PENDING 檢查非同步 IO 是否完成 WaitForSingleObject olhEvent INFINITE 等待裝置核心物件（檔案）被觸發。 CloseHandle hEvent CloseHandle hFile 可喚醒 IO 非同步可喚醒 IO 操作透過 ReadFileExWriteFileEx 函式指出完成過程回撥函式。回撥函式在該執行緒的可喚醒等待（alertable wait）中被執行。 完成埠 使用 CreateIoCompletionPort 函式建立一個完成埠。然後把檔案控制代碼繫結到這個完成埠（透過 CreateIoCompletionPort 函式。這個檔案控制代碼上的非同步 IO 操作完成時，會自動向這個完成完成埠發通知。執行緒透過 GetQueuedCompletionStatus 函式等待這個完成埠上的完成通知，然後從 GetQueuedCompletionStatus 的呼叫返回處恢復執行緒執行。 執行緒池 IO 完成物件 使用 CreateThreadpoolIo 函式建立一個 IO 完成物件，綁定了要執行非同步 IO 操作的檔案控制代碼與待執行的回撥函式。透過 StartThreadpoolIo 函式開始 IO 完成物件的工作。每當繫結的檔案控制代碼上的非同步 IO 操作完成，自動呼叫執行緒池上的執行緒執行指定的回撥函式。 例子： VOID CALLBACK OverlappedCompletionRoutine PTP_CALLBACK_INSTANCE pInstance PVOID pvContext PVOID pOverlapped ULONG IoResult ULONG_PTR NumberOfBytesTransferred PTP_IO pIo printf OverlappedCompletionRoutine transferred d bytesn NumberOfBytesTransferred HANDLE hFile CreateFileW Ldatxt 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 的結構 olOffset 2 從檔案的第三個位元組開始 IO BOOL rt WriteFile hFile buffer 5 NULL ol 發起一個非同步寫操作 if rtFALSE GetLastError ERROR_IO_PENDING Sleep 4000 do somethings else CancelThreadpoolIo pio WaitForThreadpoolIoCallbacks piofalse CloseHandle hFile CloseThreadpoolIo pio 關閉執行緒池 io 完成物件 參見 IOCP 參考文獻 外部連結 The C10K Problem a survey of asynchronous IO methods with emphasis on scaling by Dan Kegel Article Boost application performance using asynchronous IO by M Tim Jones Article Lazy Asynchronous IO For EventDriven Servers by Willy Zwaenepoel Khaled Elmeleegy Anupam Chanda and Alan L Cox Perform IO Operations in Parallel Description from POSIX standard Inside IO Completion Ports by Mark Russinovich Asynchronous IO and The Asynchronous Disk IO Explorer IOAIO is a Perl module offering an asynchronous interface for most IO operations ACE Proactor Category 併發控制