Reputation: 11047
I'm about to implement my first Windows service. The service will connect to a Bluetooth dongle, and liaison some commands and data to a single client process. Each process (client, server), shall have at least two thread - one blocking on Read(), another crunching business logic and doing an occasionally Write().
Checking the alternatives, I've decided to go with Named Pipes for IPC, but I'm having trouble understanding some of the settings. Specifically:
FILE_FLAG_OVERLAPPED
, even though I do not intend to do reads and writes on the same thread?OVERLAPPED
structure to ReadFile()
, WriteFile()
, use GetOverlappedResult()
etc? If so, what is the rational behind this?EDIT
I wish to clarify the question:
FILE_FLAG_OVERLAPPED
change this behavior?Upvotes: 4
Views: 4699
Reputation: 39591
You don't need to use FILE_FLAG_OVERLAPPED if all you're doing is reading and writing using the same handle at the same time. Other threads reading or writing to the same end of the pipe won't cause it to block. You only need it if you want to perform asynchronous I/O, which apparently you don't.
If you do use the FILE_FLAG_OVERLAPPED you must pass a valid OVERLAPPED structure to ReadFile and WriteFile via the lpOverlapped argument. If you don't use this flag and the handle isn't seekable (eg. a named pipe) then you must pass NULL instead.
The big advantage of using single threaded asynchronous I/O over a multi-threaded implementation is that you don't have to worry about concurrency issues. You can't have race conditions and deadlocks if you only have one thread. (Actually in your case, since you would still have two threads, one in the server and one the client, you can still have deadlocks and maybe race conditions if you really try, but asynchronous I/O would still make it easier to avoid them.)
Upvotes: 2
Reputation: 51413
To enable bi-directional access to a pipe, you have to specify the PIPE_ACCESS_DUPLEX flag for the dwOpenMode parameter. Asynchronous operation (FILE_FLAG_OVERLAPPED
) is not strictly required to enable bi-directional mode.
Using asynchronous I/O, however, is recommended for bi-directional pipes. It allows you to issue both read and write operations at the same time, on the same thread (see WaitForMultipleObjects). Either operation is signaled upon completion. This prevents a lengthy write operation from blocking a potential read, for example, and you'll be able to respond to either one in a timely manner. Maybe even more importantly, since you never know when data is available, you'll typically want to always issue a read operation, without having it block your thread.
This is outlined in the documentation for CreateNamedPipe:
If [overlapped] mode is enabled, functions performing read, write, and connect operations that may take a significant time to be completed can return immediately. This mode enables the thread that started the operation to perform other operations while the time-consuming operation executes in the background. For example, in overlapped mode, a thread can handle simultaneous input and output (I/O) operations on multiple instances of a pipe or perform simultaneous read and write operations on the same pipe handle. If overlapped mode is not enabled, functions performing read, write, and connect operations on the pipe handle do not return until the operation is finished. The ReadFileEx and WriteFileEx functions can only be used with a pipe handle in overlapped mode. The ReadFile, WriteFile, ConnectNamedPipe, and TransactNamedPipe functions can execute either synchronously or as overlapped operations.
Upvotes: 2