QueueUserAPC
The QueueUserAPC function adds a user-mode asynchronous procedure call (APC) object to the APC queue of the specified thread.
DWORD QueueUserAPC(
PAPCFUNC pfnAPC, // pointer to APC function
HANDLE hThread, // handle to the thread
DWORD dwData // argument for the APC function
);
The APC support provided in the operating system allows an application to queue an APC object to a thread. Each thread has its own APC queue. The queuing of an APC is a request for the thread to call the APC function.The operating system issues a software interrupt to direct the thread to call the APC function.(若线程处于监听状态,系统通过软件中断调用APC例程)
When a user-mode APC is queued, the thread is not directed to call the APC function unless it is in an alertable state. After the thread is in an alertable state, the thread handles all pending APCs in first in, first out (FIFO) order, (线程处于监听状态,会以先进先出的顺序处理所有的APC例程)
and the wait operation returns WAIT_IO_COMPLETION.
Athread enters an alertable state by using SleepEx, SignalObjectAndWait, WaitForSingleObjectEx, WaitForMultipleObjectsEx,
or MsgWaitForMultipleObjectsEx to perform an alertable wait operation. Note that you can not use WaitForSingleObjectEx to wait on the handle to the object for which the APC is queued. Otherwise, when the asynchronous operation is completed, the handle is set to the signaled state and the thread is no longer in an alertable wait state, so the APC function will not be executed. However, the APC is still queued, so the APC function will be executed if you call another alertable wait function. (所以说的线程进入异步过程调用处理其APC队列后,wait函数返回线程再也不是处于监听状态了,除非再次调用alertable wait fuction)
If an application queues an APC before the thread begins running, the thread begins by calling the APC function.
Once the thread calls an APC function, it calls the APC functions for all APCs in its APC queue.
(当线程处理APC例程时,会处理所有的例程)
When the thread is terminated using the ExitThread or TerminateThread function, the APCs in its APC queue are lost. The APC functions are not called.
Note that the ReadFileEx, SetWaitableTimer, and WriteFileEx functions are implemented using an APC as the completion notification callback mechanism.(即ReadFileEx和WriteFileEx的完成例程的回调机制是通过APC实现,但线程必须在调用这些函数后进入监听状态(alertable).
DWORD WaitForSingleObjectEx(
HANDLE hHandle, // handle to object to wait for
DWORD dwMilliseconds, // time-out interval, in milliseconds
BOOL bAlertable // return to execute I/O completion routine if TRUE
);
The WaitForSingleObjectEx function returns when one of the following occurs:
1.The specified object is in the signaled state.
2.An I/O completion routine or asynchronous procedure call (APC) is queued to the thread.
(线程的apc队列中有完成例程等待调用)
3.The time-out interval elapses.
DWORD SleepEx(
DWORD dwMilliseconds, // time-out interval in milliseconds
BOOL bAlertable // early completion flag
);
The SleepEx function causes the current thread to enter a wait state until one of the following occurs:
1.An I/O completion callback function is called
2.An asynchronous procedure call (APC) is queued to the thread.
3.The time-out interval elapses
WriteFileEx
The WriteFileEx function writes data to a file. It is designed solely for asynchronous operation, unlike WriteFile, which is designed for both synchronous and asynchronous operation.
WriteFileEx reports its completion status asynchronously, calling a specified completion routine when writing is completed or canceled and the calling thread is in an alertable wait state.(这个函数用于异步调用,当其线程处于监听状态时完成例程才能被调用)
BOOL WriteFileEx(
HANDLE hFile, // handle to output file
LPCVOID lpBuffer, // pointer to input buffer
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPOVERLAPPED lpOverlapped, // pointer to async. i/o data
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
// pointer to completion routine
);
FileIOCompletionRoutine
The FileIOCompletionRoutine function is an application-defined callback function used with the ReadFileEx or WriteFileEx function. It is called when the asynchronous input and output (I/O) operation is completed or canceled and the calling thread is in an alertable state (using the SleepEx, MsgWaitForMultipleObjectsEx, WaitForSingleObjectEx, or WaitForMultipleObjectsEx function with the fAlertable flag set to TRUE).
The LPOVERLAPPED_COMPLETION_ROUTINE type defines a pointer to this callback function. FileIOCompletionRoutine is a placeholder for the application-defined function name.
VOID CALLBACK FileIOCompletionRoutine(
DWORD dwErrorCode, // completion code
DWORD dwNumberOfBytesTransfered, // number of bytes transferred
LPOVERLAPPED lpOverlapped // pointer to structure with I/O
// information
);
而在异步方面,WriteFileEx与WriteFile的区别在于,在异步操作完成之后的二者所采用的完成通知方式不同,WriteFileEx采用完成通知回调函数机制(即异步过程调用,前面已说明是采用APC实现),WriteFile是采用重叠I/O模型.当操作完成后OVERLAPPED中的事件句柄设置有信号状态( The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the read operation )。WriteFileEx要求其调用线程处于监听状态才能调用指定的回调函数,而WriteFile则需要在投递写文件操作后可以做些其他处理但一定要有个WaitForSingleObject等待OVERLAPPED中的事件句柄,得到写文件的完成通知以了解完成状态。