Как я могу выполнить сетевой ввод-вывод в самом конце жизненного цикла процесса? - PullRequest
3 голосов
/ 27 сентября 2010

Я разрабатываю DLL на C ++, которой необходимо записать некоторые данные через (ранее установленное) соединение TCP / IP с помощью вызова write () .Чтобы быть точным, DLL должна отправить небольшое сообщение: «Процесс 12345 завершается в 2007-09-27 15:30:42, значение i равно 131», когда процесс прерывается.

К сожалениювсе известные мне способы определения окончания процесса, по-видимому, слишком запоздали для любых сетевых вызовов.В частности, я попробовал следующие подходы, и вызов write () возвращал -1 в каждом случае:

  1. Вызов write () из деструктораглобальный объект.
  2. Вызов write () из функции обратного вызова, зарегистрированной с использованием atexit () .
  3. Вызов write () из DllMain (в случае, если аргумент reason равен DLL_PROCESS_DETACH).Я знаю, что это небезопасно, но я немного отчаялся.: -)

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

Кто-нибудь знает, как это сделать?

Ответы [ 5 ]

3 голосов
/ 27 сентября 2010

Рассмотрите возможность мониторинга процесса из отдельного сторожевого процесса.

Определение выхода из процесса: http://msdn.microsoft.com/en-us/library/y111seb2(v=VS.71).aspx

Учебник. Управление процессом Windows: http://msdn.microsoft.com/en-us/library/s9tkk4a3(v=VS.71).aspx

2 голосов
/ 27 сентября 2010

Рекомендуется использовать Объекты заданий Windows .

Ваша основная программа (программа мониторинга, которая будет использовать, например, send () ) может запустить дочерний процесс, приостановленный,поместите это в работу и затем возобновите.Затем он будет работать в объекте задания.Вы можете зарегистрировать уведомление через SetInformationJobObject с JobObjectAssociateCompletionPortInformation.Затем вы будете уведомлены, если в задании будет создан какой-либо дочерний процесс и будет ли завершен какой-либо процесс внутри задания.Таким образом, вы сможете отправить все, что вам нужно из процесса мониторинга .Если вы отлаживаете программу в Visual Studio, она также использует объекты заданий для управления вашим процессом и всеми дочерними процессами, которые вы запускаете.

Я успешно использую технику в C ++ и в C #.Поэтому, если у вас возникнут проблемы с реализацией, я могу опубликовать пример кода.

0 голосов
/ 27 сентября 2010

Где Winsock закрывается с помощью WSACleanup ? Вы должны убедиться, что ваш ввод / вывод завершен до того, как это произойдет.

Вы должны быть в состоянии разобраться, если это происходит, поместив точку останова на вызов Win32 в Winsock2.dll. Выгрузка DLL отображается в выводе в окне отладки.

0 голосов
/ 27 сентября 2010

Почему? Просто закройте розетку. Если это единственное закрытие в программе, которое, по вашему описанию, должно быть, говорит другому концу о завершении этого конца, и вы можете отправить информацию об идентификаторе процесса в начале, а не в конце. Вы не должны делать ничего трудоемкого или потенциально блокирующего в выходном хуке или статическом деструкторе.

0 голосов
/ 27 сентября 2010

Я предлагаю выбрать вариант 3. Просто сделайте загрузку / выгрузку DLL правильно, и все в порядке.Звонок write() должен работать, я не могу объяснить, почему это не в вашем случае.Возможно ли сбой вызова по другой причине, которая не связана?

Работает ли это, если вы вручную вызываете функцию DLL из главного приложения?

...