Каковы последствия вызова CloseHandle несколько раз?
В документах говорится, что "Вы не были должны", но я думаю, что у меня есть реалистический случай с именованными каналами, где дескриптор мог бы быть закрыт внешне (См. конец сообщения).
CloseHandle выдает исключение в режиме отладки в этом случае, который предлагает мне, разработчики думают, что это серьезно, но документы не являются точно четкими.
(Вежливый запрос: избегайте, чтобы ответ "просто не делал!" :-). Конечно, нужно постараться не закрывать дескриптор несколько раз, и конечно существуют хорошие методы для помощи с этим: я просто интересуюсь тем, что происходит, если Вы не делаете).
Я услышал, что некоторые люди предполагают, что, если дескриптор был быстро снова использован ОС, Вы могли бы закончить тем, что закрыли другого, другой дескриптор.
Это, вероятно?
Как Windows выбирает идентификаторы дескриптора?
Есть ли гарантия о том, как регулярно значение дескриптора будет снова использовано?
(например, TCP гарантирует, что номер порта не может быть снова использован в течение определенного периода времени).
Можно ли закрыть дескрипторы через типы дескриптора? Например, я мог думать, что закрываю канал, но заканчиваю тем, что закрыл Событие?
Спасибо!
John
(Контекст к этому: я использую именованные каналы в клиент-серверной модели. Кажется мне очень трудным гарантировать, что точно одна сторона, как гарантируют, закроет дескриптор, например, в процессе отказывают/уничтожают случай. Возможно, я неправ, но конечно пример кода MSDN, кажется, по моему мнению позволяет клиенту закрывать общий дескриптор, и затем когда сервер пытается закрыть его, он уже закрывается).
Достаточно просто проверить:
HANDLE h = 0;
h = CreateMutex(NULL, TRUE, NULL);
printf("%X\n", h);
CloseHandle(h);
h = 0;
h = CreateMutex(NULL, TRUE, NULL);
printf("%X\n", h);
В моем WinXP x64 получилось:
2E8
2E8
Итак, вот оно.
В отличие от портов TCP, дескрипторы обрабатываются немедленно.
Повторите этот эксперимент с вашим любимым API или любым их сочетанием.
Могут произойти две вещи:
ИМХО, ни то, ни другое не особо привлекательно.
Вероятно, вы неправильно представляете себе трубу. У нее два конца, каждый из которых представлен разной ручкой. Да, CloseHandle нужно вызвать дважды, чтобы экземпляр трубы исчез. Но поскольку это разные хэндлы, это не может вызвать никаких проблем. Также обратите внимание, что экземпляры хэндлов зависят от процесса. Даже если они имеют одинаковое значение в обоих процессах, они не ссылаются на одну и ту же конечную точку трубы.