Linux поддерживает отправку произвольного Posix-сигнала, такого как SIGINT или SIGTERM, процессу с помощью kill-Command. В то время как SIGINT и SIGTERM - это просто утомительные старые способы завершить процесс дружественным или не очень дружественным способом, SIGQUIT предназначен для запуска дампа ядра. Это можно использовать для запуска запущенной виртуальной машины Java для распечатки дампа потока, включая трассировки стека всех запущенных потоков - аккуратно! После печати отладочной информации виртуальная машина Java продолжит делать то, что делала раньше; фактически дамп потока просто происходит в другом порожденном потоке с максимальным приоритетом. (Вы можете попробовать это сами, используя kill -3 <VM-PID>.)
Обратите внимание, что вы также можете зарегистрировать свои собственные обработчики сигналов, используя (неподдерживаемые!) Классы Signal и SignalHandler в пакете sun.misc, так что вы можете повеселиться с ними.
Однако мне еще предстоит найти способ отправить сигнал процессу Windows. Сигналы создаются определенным пользовательским вводом: например, Ctrl-C запускает SIGINT на обеих платформах. Но похоже, что нет никакой утилиты для ручной отправки сигнала запущенному, но не интерактивному процессу в Windows. Очевидное решение - использовать исполняемый файл Cygwin kill, но, хотя он может завершить процессы Windows с помощью соответствующего Windows API, я не смог отправить с ним SIGBREAK (эквивалент Windows SIGQUIT); на самом деле я думаю, что единственный сигнал, который он может посылать процессам Windows, - это SIGTERM.
Итак, чтобы сделать длинную историю короче и повторить заголовок: как отправить произвольный сигнал процессу в Windows?
Sun предостерегает от использования классов в иерархии com.sun просто потому, что они могут (и делают) произвольно изменяться между версиями, а иногда даже между платформами.
Я это знаю, поэтому написал "неподдерживаемый" (восклицательный знак). Это было просто отступление и не главное в вопросе.




Вы также можете использовать jconsole для просмотра трассировки стека всех запущенных потоков. Это будет работать в Windows и любой другой ОС, поддерживающей Java. jconsole также имеет множество других полезных функций, графики памяти, графики процессоров и т. д.
Он не отвечает на ваш исходный вопрос, но, надеюсь, позволяет получить те же результаты.
Если вы не знакомы с jconsole, ознакомьтесь с документацией Использование JConsole.
Мне просто интересно, поможет ли вам PsИнструменты от SysInternals, теперь принадлежащего Microsoft.
У меня не сработало (pskillне ведет себя как Ctrl + C или Ctrl + Break ...)
Windows - это не POSIX. У него нет сигналов. Единственные «сигналы», которые получают консольные программы, - это вызовы SetConsoleCtrlHandler, и в этом случае можно получить уведомление о том, что пользователь нажал Ctrl + C, Ctrl + Break, закрыл окно консоли, вышел из системы или выключил систему.
Все остальное делается с помощью IPC, обычно с помощью оконных сообщений или RPC. Проверьте документацию Sun, чтобы узнать, есть ли способ сделать то, что вы просите, в Windows JRE.
В Windows все вращается вокруг сообщений Win32. Я не верю, что для этого есть инструмент командной строки, но в C++ вы можете использовать FindWindow для отправки произвольного сообщения в другую программу Windows. например.:
#define WM_MYMSG ( WM_USER+0x100 )
HWND h = ::FindWindow(NULL,_T("Win32App"));
if (h) {
::PostMessage(h, WM_MYMSG, 0, 0);
}
Это также можно сделать на C# с помощью com-взаимодействия.
Если вы хотите явно / программно убить другую программу / процесс любого типа, в pstools SysInternals есть небольшой инструмент под названием «pskill», который ведет себя так же, как Unixen «kill».
Если вам нужно что-то еще, продолжайте читать (хотя я могу ошибаться в некоторых деталях, приведенных ниже - с тех пор как я последний раз разрабатывал программу Windows на C, используя только WinAPI и прекрасные книги Чарльза Петцольда «Программирование для Windows» в качестве руководства, то прошло много времени). ).
В Windows у вас нет должным образом «сигналов», какие функции WinMain и WinProc получают от операционной системы - это просто Сообщения. Например, когда вы нажимаете кнопку «X» окна, Windows отправляет обработчику этого окна сообщение WM_CLOSE. Когда окно удалено, но программа все еще работает, оно отправляет WM_DESTROY. Когда он собирается выйти из основного цикла обработки сообщений, WinMain (не WinProc) получает WM_QUIT. Ваша программа должна реагировать на все это, как и ожидалось - вы действительно можете разработать «незащищенное» приложение, не делая то, что оно должно, после получения сообщения WM_CLOSE.
Когда пользователь выбирает задачу в диспетчере задач Windows и нажимает «Завершить задачу», ОС отправляет WM_CLOSE (и еще один, который я не помню). Однако, если вы используете «Завершить процесс», процесс удаляется напрямую, сообщения не отправляются никогда (источник: Старая новая вещь
Я помню, что был способ получить HWND окна другого процесса, как только вы узнаете, что другой процесс может отправить этому окну сообщение через функции PostMessage и DispatchMessage.
Я также не думаю, что Windows отправляет WM_QUIT, по крайней мере, при закрытии окна.
Ах, вы попросили меня исследовать это ... что всегда хорошо, так как прошло много времени с тех пор, как я разрабатывал напрямую с помощью Win API. Теперь мне стало понятнее.
это просто поведение приложений пользовательского интерфейса - если ваше приложение не имеет пользовательского интерфейса (например, консольные приложения), этот ответ неверен, одна из возможностей иметь собственное завершение работы или закрытие крючка без пользовательского интерфейса - это msdn.microsoft.com/de-de/library/windows/desktop/…
Ruby каким-то образом может (по крайней мере, имитировать) SIGINT SIGKILL и т.д. в Windows и перехватывать эти сообщения. Может, захочешь это проверить.
Как ruby «посылает сигнал SIGINT этому процессу» внизу, в окнах, на самом деле вызывает TerminateProcess или эквивалент для этого PID.
Существует также эквивалентный Windows метод для "ловли ctrl + c", я полагаю, это то, что он там вызывает.
Пример как?
ОК добавил еще, или вы хотите пример рубина? :)
SIGINT и другие сигналы могут быть отправлены программе с использованием windows-kill, с помощью синтаксиса windows-kill -SIGINT PID, где PID может быть получен с помощью Microsoft pslist.
Что касается перехвата SIGINT, если ваша программа написана на Python, вы можете реализовать обработку / перехват SIGINT, как в это решение.
Я сам искал сгенерировать дамп стека ... очень жаль, что Sun не добавила такую возможность сделать это из иконки Java в трее.