Действительно ли это безопасно к “двойному завершению” использование дескриптора CloseHandle?

Каковы последствия вызова CloseHandle несколько раз?

В документах говорится, что "Вы не были должны", но я думаю, что у меня есть реалистический случай с именованными каналами, где дескриптор мог бы быть закрыт внешне (См. конец сообщения).

CloseHandle выдает исключение в режиме отладки в этом случае, который предлагает мне, разработчики думают, что это серьезно, но документы не являются точно четкими.

(Вежливый запрос: избегайте, чтобы ответ "просто не делал!" :-). Конечно, нужно постараться не закрывать дескриптор несколько раз, и конечно существуют хорошие методы для помощи с этим: я просто интересуюсь тем, что происходит, если Вы не делаете).

Я услышал, что некоторые люди предполагают, что, если дескриптор был быстро снова использован ОС, Вы могли бы закончить тем, что закрыли другого, другой дескриптор.

Это, вероятно?

Как Windows выбирает идентификаторы дескриптора?

Есть ли гарантия о том, как регулярно значение дескриптора будет снова использовано?

(например, TCP гарантирует, что номер порта не может быть снова использован в течение определенного периода времени).

Можно ли закрыть дескрипторы через типы дескриптора? Например, я мог думать, что закрываю канал, но заканчиваю тем, что закрыл Событие?

Спасибо!

John

(Контекст к этому: я использую именованные каналы в клиент-серверной модели. Кажется мне очень трудным гарантировать, что точно одна сторона, как гарантируют, закроет дескриптор, например, в процессе отказывают/уничтожают случай. Возможно, я неправ, но конечно пример кода MSDN, кажется, по моему мнению позволяет клиенту закрывать общий дескриптор, и затем когда сервер пытается закрыть его, он уже закрывается).

6
задан John 5 July 2010 в 11:03
поделиться

3 ответа

Достаточно просто проверить:

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 или любым их сочетанием.

12
ответ дан 8 December 2019 в 13:43
поделиться

Могут произойти две вещи:

  1. Вы закрываете дескриптор, открытый другим кодом. Это, вероятно, не повлияет на ваш код, но, вероятно, будет иметь катастрофические последствия для другого кода.
  2. Если вы работаете с подключенным отладчиком, ваше приложение вылетает из строя, потому что ОС вызывает исключение, когда обнаруживает закрытие недопустимого дескриптора.

ИМХО, ни то, ни другое не особо привлекательно.

1
ответ дан 8 December 2019 в 13:43
поделиться

Вероятно, вы неправильно представляете себе трубу. У нее два конца, каждый из которых представлен разной ручкой. Да, CloseHandle нужно вызвать дважды, чтобы экземпляр трубы исчез. Но поскольку это разные хэндлы, это не может вызвать никаких проблем. Также обратите внимание, что экземпляры хэндлов зависят от процесса. Даже если они имеют одинаковое значение в обоих процессах, они не ссылаются на одну и ту же конечную точку трубы.

4
ответ дан 8 December 2019 в 13:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: