WSACleanup и atExit - PullRequest
       27

WSACleanup и atExit

6 голосов
/ 09 июня 2009

Можно ли зарегистрировать WSACleanup через функцию atExit? У нас есть несколько приложений, которые могут завершать работу в разных точках кода, поэтому мы хотели бы избежать размещения WSACleanup везде через код. В настоящий момент мы вызываем WSAStartup / WSACleanup через DllMain, поскольку у нас есть dll, который используется всеми этими приложениями. Однако Microsoft строго рекомендует не использовать WSAStartup / WSACleanup через DllMain, поскольку это может привести к взаимоблокировкам. Мы можем переместить WSAStarup из DllMain и вызвать его в одной точке кода для всех приложений, прежде чем они получат доступ к библиотеке сокетов Windows. И, как только мы вызываем WSAStartup, мы хотели бы использовать функцию atExit для регистрации вызова WSACleanup. У кого-нибудь есть опыт с этим подходом? Спасибо!

Ответы [ 3 ]

4 голосов
/ 09 июня 2009

Если у вас есть многопоточное приложение, и некоторые потоки все еще подключены, приложениям на другом конце может не понравиться способ завершения соединения. Поэтому предпочтительно завершить все коммуникации упорядоченным образом до того, как main () завершит работу, и когда вы это сделаете, вы также можете вызвать WSACleanup.

2 голосов
/ 10 июня 2009

Я согласен, что подход RAII является благоприятным.

Однако, предупреждающее слово: atExit, смешанный с dll и дескрипторами, разбит на окнах. К сожалению, это также влияет на RAII, поскольку это реализуется с помощью обработчиков atExit в среде выполнения c ++.

Порядок вызова обработчиков atexit в windows:

  1. где-то вызывается выход или main () выходит за рамки
  2. atexit обработчики, определенные в процессе, называются.
  3. все ручки уничтожены.
  4. Вызываются обработчики atexit, определенные в dll.

Неважно, регистрируются ли обработчики atexit в dll до того, как обработчики в процессе сначала вызываются обработчики процесса, а дескрипторы уничтожаются до вызова обработчиков dll. Это приводит к исключениям win32, когда вызывается код очистки, поскольку все дескрипторы, принадлежащие dll, больше не действительны.

Это код эффекта, который содержит дескрипторы потоков, мьютексов, файлов, сокетов и т. Д. Если они размещены в dll, то их необходимо очистить перед вызовом exit или нет вообще.

Кстати, я не против окна, если я ошибаюсь или кто-то знает что-то об этом, я хотел бы знать, так как это причиняет мне невыразимую боль при очистке приложения. Я понял, что это отладка обработки выхода во время выполнения c ++ после получения исключений win32 при выходе из приложений.

Мне пришлось удалить все вызовы, чтобы выйти из моего кода. Теперь я убедился, что никакие статические данные в dll не управляют дескриптором. Все статические дескрипторы управляются объектами, которые разрушаются, когда main выходит из области видимости.

1 голос
/ 09 июня 2009

Ну, я думаю, atExit не следует использовать. Вы должны следовать принципу RAII обертывания инициализации и уничтожения библиотеки сокетов в классе.

...