Platform SDK: Interprocess Communications |
The ReadFile, WriteFile, TransactNamedPipe, and ConnectNamedPipe functions can run either synchronously or asynchronously. When a function runs synchronously, it does not return until the operation it is performing is completed. This means that the execution of the calling thread can be blocked for an indefinite period while it waits for a time-consuming operation to be completed. When a function runs asynchronously, it returns immediately, even if the operation has not been completed. This enables a time-consuming operation to be executed in the background while the calling thread is free to perform other tasks.
Using synchronous I/O enables a pipe server to use a loop that performs the following steps:
Overlapped operations make it possible for one pipe to read and write data simultaneously and for a single thread to perform simultaneous I/O operations on multiple pipe handles. This enables a single-threaded pipe server to handle communications with multiple pipe clients efficiently. For an example, see Named Pipe Server Using Overlapped I/O.
For a pipe server to use synchronous operations to communicate with more than one client, it must create a separate thread for each pipe client so that one or more threads can run while other threads are waiting. For an example of a multithreaded pipe server that uses synchronous operations, see Multithreaded Pipe Server.
The ReadFile, WriteFile, TransactNamedPipe, and ConnectNamedPipe functions can be performed asynchronously only if you enable overlapped mode for the specified pipe handle and specify a valid pointer to an OVERLAPPED structure. If the OVERLAPPED pointer is NULL, the function return value can incorrectly indicate that the operation has been completed. Therefore, it is strongly recommended that if you create a handle with FILE_FLAG_OVERLAPPED and want asynchronous behavior, you should always specify a valid OVERLAPPED structure.
The hEvent member of the specified OVERLAPPED structure must contain a handle to a manual-reset event object. This is a synchronization object created by the CreateEvent function. The thread that initiates the overlapped operation uses the event object to determine when the operation has finished. You should not use the pipe handle for synchronization when performing simultaneous operations on the same handle because there is no way of knowing which operation's completion caused the pipe handle to be signaled. The only reliable technique for performing simultaneous operations on the same pipe handle is to use a separate OVERLAPPED structure with its own event object for each operation. For more information about event objects, see Synchronization.
When ReadFile, WriteFile, TransactNamedPipe, and ConnectNamedPipe operations are performed asynchronously, one of the following occurs:
The ReadFileEx and WriteFileEx functions provide another form of overlapped I/O. Unlike the overlapped ReadFile and WriteFile functions, which use an event object to signal completion, the extended functions specify a completion routine. A completion routine is a function that is queued for execution when the read or write operation is finished. The completion routine is not executed until the thread that called ReadFileEx and WriteFileEx starts an alertable wait operation by calling one of the alertable wait functions with the fAlertable parameter set to TRUE. In an alertable wait operation, the functions also return when a ReadFileEx or WriteFileEx completion routine is queued for execution. A pipe server can use the extended functions to perform a sequence of read and write operations for each client that connects to it. Each read or write operation in the sequence specifies a completion routine, and each completion routine initiates the next step in the sequence. For an example, see Named Pipe Server Using Completion Routines.