Изучаю данную тему.
Первым что прочитал - статья Игоря Шевченко, затем MSDN.
Итак по-порядку.
=== 1 вопрос ===
Жизненный цикл pipe-сервера представляет собой, как я понял, следующий вид (синхронный режим):
1. hPipe = CreateNamedPipe
2. ConnectNamedPipe(hPipe)
3. CreateThread(hPipe)
4. Переход в пункт 1.
В потоке происходит работа с каналом и его закрытие:
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
Про ConnectNamedPipe, написано, что она возвращает False, если клиент подключился между вызовами CreateNamedPipe и ConnectNamedPipe (пункты 1 и 2 в списке).
Возникает следующий вопрос, а что будет если два клиента подключатся почти одновременно, так, что второй клиент подключится после вызова ConnectNamedPipe, но перед новым вызовом CreateNamedPipe?
=== 2 вопрос ===
Вопрос касается примера Игоря Шевченко.
http://www.delphimaster.ru/articles/named_pipes/Пример, как написано в статье, асинхронной работы с каналами. Я тоже хочу использовать асинхронный режим работы, чтобы иметь возможность корректно выходить из потока.
Но в примере используется синхронный вызов:
ConnectNamedPipe(hPipe, nil);
После чего поток заблокируется на этой строке до подключения нового клиента, а значит не даст себя корректно завершить.
Вопрос, каким образом можно разблокировать (или не блокировать) этот вызов?
Какой вариант наиболее приемлем:
- Использовать OVERLAPPED структуру,
- Для корректного завершения потока просто выполнить CloseHandle (hPipe), после чего вызов ConnectNamedPipe разблокируется с ошибкой,
- или Фиктивно подключится к каналу?
В MSDN для функции ConnectNamedPipe написано следующее: Note Nonblocking mode is supported for compatibility with Microsoft LAN Manager version 2.0, and it should not be used to achieve asynchronous input and output (I/O) with named pipes.
Я так и не понял точно, что это означает, прошу уточнить: Функцию ConnectNamedPipe нельзя использовать в асинхронном режиме или вообще работа с каналами недопустима в асинхронном режиме?
P.S. В коде, возможно ошибка. Неправильный порядок вызовов: сначала закрываем указатель, затем используем его.
CloseHandle (hPipe);
CloseHandle (hEventRd);
CloseHandle (hEventWrt);
DisconnectNamedPipe (hPipe);
На этом пока все. Спасибо заранее за терпение.