Отправкапроизвольного сигнала в Windows?
Linux поддерживает отправку произвольных Posix-Сигнала, таких как SIGINT или SIGTERM к процессу, с помощью kill -Команда. В то время как SIGINT и SIGTERM просто скучно старые способы, чтобы завершить процесс в дружественной или не очень дружелюбный вид способом, SIGQUIT призван инициировать создание дампа памяти. Это может быть использовано для запуска под управлением Java VM для печати дамп потоков, в том числе stacktraces всех запущенных потоков-ловко! После печати данные отладки Java VM и впредь будут делать все, что он делал раньше, в самом деле нить дампа всего происходит в другой породил поток максимальный приоритет. (Вы можете попытаться сделать это самостоятельно, используя kill -3 .)
обратите Внимание, что вы также можете зарегистрировать свой сигнал использование обработчиков (не поддерживается!) Signal и SignalHandler классы в sun.misc -пакет, так что вы можете есть все виды развлечений.
тем не менее, я до сих пор найти способ, чтобы послать сигнал процессу Windows. Сигналы создаются определенные входы: Ctrl-C запускает SIGINT на обеих платформах, например. Но не похоже, чтобы быть полезным вручную послать сигнал запущенным, но не интерактивного процесса в Windows. Очевидное решение состоит в том, чтобы использовать Cygwin kill executable, но в то время как это может закончиться Windows-процессов с использованием соответствующих Windows API, я не смог послать SIGBREAK (Windows эквивалентно SIGQUIT ); в самом деле, я думаю, что только сигнал, он может направить в Windows процессов SIGTERM .
Итак, чтобы сделать длинную историю короткой и повторить заголовок: Как мне отправить произвольное сигнал процессу, в Windows?
Отправка произвольного сигнала в Windows?
Linux поддерживает отправку произвольного Posix-сигнала, такого как SIGINT или SIGTERM , в процесс с помощью kill -Command. В то время как SIGINT и SIGTERM являются просто скучными старыми способами прекращения процесса в дружественном или не-дружественном виде, SIGQUIT предназначен для запуска дампа ядра. Это можно использовать для запуска запущенной виртуальной машины Java для печати дампа потока, включая стек стеков всех работающих потоков — аккуратно! После печати информации об отладке Java VM продолжит делать то, что было раньше; на самом деле свалка потока происходит только в другом порожденном потоке с максимальным приоритетом. (Вы можете попробовать это самостоятельно, используя kill -3 .)
Обратите внимание, что вы также можете регистрировать свои собственные обработчики сигналов с помощью классов (неподдерживаемых!) Signal и SignalHandler в sun.misc -пакете, поэтому вы можете иметь с ним всевозможные удовольствия.
Однако мне еще предстоит найти способ отправки сигнала в процесс Windows. Сигналы создаются с помощью определенных пользовательских входов: Ctrl-C запускает a SIGINT на обеих платформах, например. Но, похоже, нет никакой утилиты для ручного отправки сигнала на запущенный, но неинтерактивный процесс в Windows. Очевидным решением является использование исполняемого файла Cygwin kill , но, хотя он может завершать процессы Windows с использованием соответствующего Windows API, я не мог отправить с ним SIGBREAK (эквивалент Windows SIGQUIT ); на самом деле я думаю, что единственным сигналом, который он может отправить на процессы Windows, является SIGTERM .
Итак, чтобы сделать длинный рассказ коротким и повторить заголовок: Как отправить произвольный сигнал процессу в Windows?
Посылка произвольного сигнала в Windows?
Linux поддерживает отправку произвольного Posix-сигнала, такого как SIGINT или SIGTERM процессу с помощью команды kill . В то время как SIGINT и SIGTERM -это просто скучные старые способы закончить процесс дружелюбным или не очень дружелюбным способом, SIGQUIT предназначен для запуска дампа ядра. Это может быть использовано для запуска запущенной виртуальной машины Java, чтобы распечатать дамп потока, включая stacktraces всех запущенных потоков-аккуратно! После печати отладочной информации виртуальная машина Java продолжит выполнять все, что она делала до этого.; на самом деле дамп потока просто происходит в другом порожденном потоке с максимальным приоритетом. (Вы можете попробовать это самостоятельно, используя kill -3 .)
Обратите внимание, что вы также можете зарегистрировать свои собственные обработчики сигналов, используя (неподдерживаемый!) Signal и SignalHandler классы в sun.misc -пакете, так что вы можете иметь все виды удовольствия с ним.
однако мне еще предстоит найти способ послать сигнал в процесс Windows. сигналы создаются определенными входами пользователя: Ctrl-C триггеры a SIGINT на обоих платформы, например. Но, похоже, нет никакой утилиты, чтобы вручную отправить сигнал запущенному, но неинтерактивному процессу в Windows. Очевидным решением является использование исполняемого файла Cygwin kill , но, хотя он может завершать процессы Windows с помощью соответствующего API Windows, я не смог отправить с ним SIGBREAK (эквивалент Windows SIGQUIT ); на самом деле я думаю, что единственный сигнал, который он может послать процессам Windows, — это SIGTERM .
Итак, чтобы сделать длинную историю короткой и повторить заголовок: Как отправить произвольный сигнал процессу в Windows?
6 ответов:
Если вы хотите явно / программно убить другую программу / процесс любого рода, в pstools SysInternals есть небольшой инструмент под названием «pskill», который ведет себя так же, как Unixen» kill».
Если вы хотите что — то еще, продолжайте читать (хотя я могу ошибаться в некоторых деталях ниже-прошла целая вечность с тех пор, как я в последний раз разрабатывал программу для Windows на C, используя только WinAPI и отличные книги Чарльза Петцольда «программирование для Windows» в качестве руководства).
ВКЛ. Windows у вас нет правильных «сигналов», какие функции WinMain и WinProc получают от операционной системы-это простые сообщения. Например, когда вы нажимаете на кнопку» X » окна, Windows отправляет этому обработчику windows сообщение WM_CLOSE. Когда окно удалено, но программа все еще работает, он отправляет WM_DESTROY. Когда он собирается выйти из основного цикла обработки сообщений, WinMain (не WinProc) получает WM_QUIT. Ваша программа должна реагировать на все это, как и ожидалось — вы можете на самом деле разработать приложение «unclosable», не делая того, что он должен делать при получении WM_CLOSE.
Когда пользователь выбирает задачу из Диспетчера задач Windows и нажимает кнопку «завершить задачу», ОС отправляет WM_CLOSE (и еще один, который я не помню). Однако если вы используете «End Process», процесс убивается напрямую, никаких сообщений никогда не отправляется (источник: the Old New Thing
Я помню, что был способ получить HWND окна другого процесса, как только вы получите этот другой процесс может отправить это окно сообщение через функции PostMessage и DispatchMessage.
Windows-это не POSIX. У него нет сигналов. Единственный «сигнал», который получают консольные программы, — это вызов SetConsoleCtrlHandler , в этом случае можно уведомить, что пользователь нажал Ctrl+C, Ctrl + Break, закрыл окно консоли, вышел из системы или выключил систему.
Все остальное делается с помощью IPC, обычно с помощью сообщений окна или RPC. Проверьте документацию Sun, чтобы увидеть, есть ли способ сделать то, что вы просите на Windows JRE.
В Windows все вращается вокруг сообщений Win32. Я не верю, что существует инструмент командной строки для этого, но в C++ вы можете использовать FindWindow для отправки произвольного сообщения другой программе Windows. например:
Это также можно сделать в C# с помощью com-взаимодействия.
Вы также можете использовать jconsole для просмотра stacktrace всех запущенных потоков. Это будет работать на Windows, и любой другой ОС, которая поддерживает Java. jconsole также имеет много других приятных функций, графики памяти, графики процессора и т. д.
Это не ответ на ваш первоначальный вопрос, но, надеюсь, позволит вам получить те же результаты.
Если вы не знакомы с jconsole, ознакомьтесь с документацией Using JConsole.
Мне просто интересно, помогут ли вам PsTools от, теперь принадлежащего Microsoft, SysInternals.
Ruby каким-то образом может (по крайней мере, эмулировать) SIGINT SIGKILL и т. д. на окнах, и ловить эти сообщения. Может, стоит проверить.
Как ruby делает «send signal SIGINT to that process» внизу, в windows, на самом деле, чтобы вызвать TerminateProcess или эквивалент на этом PID.
Есть также эквивалентный метод windows для «ловли ctrl+c», я думаю, что это то, что он там называет.
Управление процессами
Взаимодействие процессов
Процессы взаимодействуют друг с другом, используя при этом разные механизмы . Процессы могут асинхронно или синхронно передавать друг другу данные, управление доступом к иным ресурсам системы.
С каждым процессом связаны три независимых потока данных: стандартный ввод (stdin), стандартный вывод (stdout) и стандартный поток сообщений об ошибках (stderr). По умолчанию все три потока связаны с тем терминалом, с которого запущен процесс ( стандартный ввод – с клавиатуры, вывод данных и ошибок – на экран). Стандартный ввод также называют входным потоком, а стандартный вывод – выходным.
Каждому из этих потоков сопосотавлены внутренние дескрипторы файлов: входному потоку – 0, выходному потоку – 1, потоку сообщений об ошибках – 2. Внутренний дескриптор файла существует только в пределах того процесса, с которым он связан. Внутренние дескрипторы в разных процессах имеют одинаковые номера, но это физически разные внутренние дескрипторы , и каждый процесс имеет свои собственные внутренние дескрипторы .
Перенаправление потоков
Поток данных , связанный с процессом, может быть перенаправлен в файл или другой поток данных . Например, если требуется, чтобы программа find выдала список имен файлов в файл names, а не на терминал, следует выполнить команду
Символ правой угловой скобки > означает перенаправление выходного потока запущенной программы в файл. При использовании этой конструкции файл names будет создан, а если он уже существует, то он будет уничтожен и будет создан новый файл с таким именем и новым содержимым.
Для добавления вывода программы в конец файла следует применять конструкцию «две правые угловые скобки» >>
В этом случае файл names будет создан, если он не существует, а если существует, выходной поток программы find добавится в конец файла .
Можно перенаправить текст из файла во входной поток.
Если время от времени вы отправляете письма по стандартной форме, например, уведомляя пользователей о том, что их домашние каталоги превышают допустимый размер, можно подготовить такое письмо в текстовом редакторе и автоматически отправлять его из скрипта, проверяющего размер каталогов, с помощью команды
Бывает необходимо отправлять пользователям не совершенно одинаковые письма, а письмо, где стандартный текст перемешан с личными обращениями и конкретными подробностями. Тогда на помощь приходит перенаправление потока посредством конструкции «документ здесь».
Это дает возможность перенаправить ввод в процесс не из файла, а прямо из командной строки (или тела скрипта):
Такой скрипт отправит по указанному адресу письмо, где вместо $TARGETUSER и $OVERSIZE будут подставлены имя того пользователя, которому предназначается письмо, и превышение лимита, соответственно. Естественно, этим переменным следует присвоить какое-то значение перед выполнением команды, но тот фрагмент скрипта, в котором это делается, вы с легкостью додумаете самостоятельно.
Указание в тексте значков показывает что все, что следует непосредственно за ними до ближайшего символа-разделителя, является ограничителем текста. Символ-разделитель – это любой пустой символ: пробел, табуляция или конец строки. Все, что идет за ограничителем текста, передается во входной поток запущенного командой процеса вплоть до момента, когда в начале новой строки не встретится такой же ограничитель текста. Ограничитель может представлять собой любой набор непустых символов – неважно, просто ли это символ «точка», слово FINAL или что-то еще.
Кроме того, что потоки могут быть перенаправлены в файл или из файла, существует возможность перенаправить выходной поток одного процесса во входной поток другого. Направьте выходной поток программы ls во входной поток программы more , чтобы длинный список файлов вывести поэкранно:
Символ вертикальной черты «|» означает перенаправление выходного потока программы, команда вызова которой находится слева от этого символа, во входной поток программы, вызываемой справа.
При обработке текста часто используется конструкция, называемая конвейером, когда одновременно запускается несколько программ, которые передают данные друг другу: выходной поток первой перенаправляется во входной поток второй, выходной поток второй – во входной поток третьей и т.д.
Например, для подсчета запущенных демонов httpd можно использовать такую конструкцию:
Программа ps выводит список всех процессов, запущенных в системе, grep выбирает из этого списка строки, в которых есть подстрока httpd , а wc с ключом l подсчитывает, как много строк оказалось в ее входном потоке.
Программы, запущенные в конвейере, начинают работать одновременно, поэтому данные на входе второй программы оказываются так скоро, как их сможет сгенерировать первая.
Сигналы
Процессы могут взаимодействовать между собой, посылая друг другу сигналы. Список сигналов в Solaris ограничен сорока двумя сигналами, из которых наиболее употребительны TERM , KILL и HUP. В разных UNIX может быть разное количество сигналов, стандарт POSIX 1.1 определяет тридцать один сигнал. Каждый из них имеет свое мнемоническое обозначение и номер. В разных системах мнемонические обозначения остаются одинаковыми, а номер может быть разным.
Обычный процесс может послать сигнал только тому процессу, который имеет такой же эффективный идентификатор владельца, т.е. запущен тем же пользователем. Процесс , работающий от имени root , может послать любой сигнал любому процессу в системе.
С помощью команды
можно послать сигнал с номером номер_сигнала процессу с идентификатором PID
В некоторых системах UNIX есть возможность послать сигнал процессу с определенным именем с помощью программы killall :
В Solaris эта программа имеет другое значение, а именно выполняет отправку сигнала завершения всем активным процессам :
А отправлять сигнал процессам с определенным именем в Solaris следует командой pkill .
С помощью pkill можно отправлять сигнал завершения TERM процессу с тем или иным признаком, отправка сигнала процессу с определенным именем – не единственное умение pkill. Например,
отправит сигнал HUP (SIGHUP) всем процессам, чья фактическая группа – other или daemon .
В табл. 9.2 приведен список сигналов, определенный стандартом POSIX 1.1, а в табл. 9.3 – список сигналов, определенных в Solaris 9.
Сигнал | Номер | Значение |
---|---|---|
SIGHUP | 1 | Разрыв связи с управляющим терминалом или управляющим процессом |
SIGINT | 2 | Прерывание с клавиатуры |
SIGQUIT | 3 | Сигнал выхода дан с клавиатуры |
SIGILL | 4 | Недопустимая инструкция |
SIGABRT | 6 | Сигнал abort получен от вызванной кем-то функции abort |
SIGFPE | 8 | exception: ошибка вычислений с плавающей запятой |
SIGKILL | 9 | Безусловное завершение процесса |
SIGSEGV | 11 | Неверный адрес памяти |
SIGPIPE | 13 | Запись в несуществующий канал |
SIGALRM | 14 | Сигнал timer от функции alarm |
SIGTERM | 15 | Завершение |
SIGUSR1 | 30,10,16 | Определяется пользователем |
SIGUSR2 | 31,12,17 | Определяется пользователем |
SIGCHLD | 20,17,18 | Дочерний процесс остановлен или принудительно завершен |
SIGCONT | 19,18,25 | Продолжить выполнение, если оно было остановлено |
SIGSTOP | 17,19,23 | Остановить процесс |
SIGTSTP | 18,20,24 | Остановить ввод с терминала |
SIGTTIN | 21,21,26 | Ввод с терминала для фонового процесса |
SIGTTOU | 22,22,27 | Вывод с терминала для фонового процесса |
Кроме команды pkill системный администратор может найти удобной команду pgrep , которая заменяет конструкцию
В Solaris для получения того же результата можно ввести более короткую команду
Название | Знач. | Действие по умолчанию | Событие |
---|---|---|---|
SIGHUP | 1 | завершение | разрыв связи с терминалом |
SIGINT | 2 | завершение | прерывание |
SIGQUIT | 3 | аварийное завершение ( core ) | Quit (see termio(7I)) |
SIGILL | 4 | аварийное завершение ( core ) | недопустимая команда процессора |
SIGTRAP | 5 | аварийное завершение ( core ) | прерывание при трассировке или точке останова |
SIGABRT | 6 | аварийное завершение ( core ) | аварийное принудительное завершение |
SIGEMT | 7 | аварийное завершение ( core ) | прерывание эмуляции |
SIGFPE | 8 | аварийное завершение ( core ) | arithmetic exception: ошибка вычислений с плавающей запятой |
SIGKILL | 9 | безусловное завершение | требование безусловного завершения |
SIGBUS | 10 | аварийное завершение ( core ) | ошибка шины |
SIGSEGV | 11 | аварийное завершение ( core ) | ошибка сегментации (выход за пределы выделенной памяти) |
SIGSYS | 12 | аварийное завершение ( core ) | неверный системный вызов |
SIGPIPE | 13 | завершение | запись в несуществующий канал |
SIGALRM | 14 | завершение | сигнал timer от функции alarm |
SIGTERM | 15 | завершение | завершение |
SIGUSR1 | 16 | завершение | программируемый сигнал 1 |
SIGUSR2 | 17 | завершение | программируемый сигнал 2 |
SIGCHLD | 18 | действия не выполняются | изменение статуса дочернего процесса |
SIGPWR | 19 | действия не выполняются | сбой питания или перезагрузка |
SIGWINCH | 20 | действия не выполняются | изменение размера окна |
SIGURG | 21 | действия не выполняются | состояние сокета (Urgent Socket Condition ) |
SIGPOLL | 22 | завершение | Pollable Event (see streamio(7I)) |
SIGSTOP | 23 | остановка | требование остановки |
SIGTSTP | 24 | остановка с терминала | остановка ввода |
SIGCONT | 25 | действия не выполняются | требование продолжения |
SIGTTIN | 26 | остановка ввода | ввод с терминала для фонового процесса |
SIGTTOU | 27 | остановка вывода | вывод с терминала для фонового процесса |
SIGVTALRM | 28 | завершение | Virtual Timer Expired |
SIGPROF | 29 | завершение | Profiling Timer Expired |
SIGXCPU | 30 | аварийное завершение ( core ) | достижение лимита времени использования процессора ( CPU time limit exceeded) |
SIGXFSZ | 31 | аварийное завершение ( core ) | превышение допустимого размера файла — getrlimit (see getrlimit(2)) |
SIGWAITING | 32 | действия не выполняются | зарезервировано библиотекой потоков |
SIGLWP | 33 | действия не выполняются | межпроцессный ( LWP ) сигнал – зарезервировано библиотекой потоков |
SIGFREEZE | 34 | действия не выполняются | Check point Freeze |
SIGTHAW | 35 | действия не выполняются | Check point Thaw |
SIGCANCEL | 36 | действия не выполняются | Cancellation signal reserved by threads library |
SIGXRES | 37 | действия не выполняются | Resource control exceeded (see setrctl(2)) |
SIGRTMIN | * | завершение | первый сигнал реального времени |
(SIGRTMIN+1) | * | завершение | второй сигнал реального времени |
(SIGRTMAX-1) | * | завершение | предпоследний сигнал реального времени |
SIGRTMAX | * | завершение | последний сигнал реального времени |
Каналы и сокеты
Процессы могут обмениваться данными друг с другом, и в UNIX предусмотрены механизмы такого обмена. Прежде всего, это каналы ( pipes ) и сокеты (sockets), которые служат для межпроцессной коммуникации, т.е. для передачи данных между одновременно запущенными процессами.
Канал – это последовательность байт , используемая как однонаправленный поток ввода/вывода.
С точки зрения программиста, бывают именованные и неименованные каналы, и способы обращения к ним несколько отличаются. При использовании канала один процесс открывает канал для чтения, другой – для записи.
Сокет – это объект, который используется для межпроцессных коммуникаций; он существует, пока какой-либо процесс хранит дескриптор, ссылающийся на него. Сокет создается системным вызовом socket , который возвращает его дескриптор. Имеется несколько типов сокетов , которые поддерживают различные возможности передачи данных .
Для каждого процесса ядро хранит таблицу внутренних дескрипторов . По-английски эта таблица называется » descriptor table «, и чтобы не путать ее с таблицей дескрипторов в файловой системе , мы называем внутреннюю таблицу дескрипторов , относящуюся к конкретному процессу, «таблицей внутренних дескрипторов «. Слово «внутренних» подчеркивает то, что эти дескрипторы существуют только в пределах процесса, который пользуется ими для обращения к файлам. Эта таблица наследуется от родительского процесса, поэтому вместе с ней наследуется и доступ к объектам, на которые ссылаются дескрипторы (файлам , каналам, сокетам).
Основными способами, при помощи которых процесс может получить дескриптор, является открытие или создание объекта, а также наследование от родительского процесса . Когда процесс завершается, ядро освобождает все дескрипторы , которые использовались этим процессом. Если процесс хранил последнюю ссылку на объект – файл или канал (т.е. в файловой системе больше не содержится записей об этом объекте), то система выполняет окончательное удаление файла ( канала ) или уничтожение сокета .
Подробнее о сокетах можно прочесть в socket (3) .
Семафоры
Семафоры – это механизм, который принято использовать для контроля доступа нескольких процессов к одному ресурсу. Есть несколько реализаций программного интерфейса ( API ), связанного с семафорами:
- вариант System V IPC (inter- process communication );
- BSD ;
- POSIX 1003.1b.
Семафор по сути – это переменная, в зависимости от значения которой доступ к тому или иному ресурсу разрешается или блокируется до его освобождения. Семафоры широко используются в Oracle. Чтобы настроить подсистему семафоров в Solaris до версии 9 включительно (обеспечить достаточное количество семафоров в ядре ), может потребоваться внести изменения в файл конфигурации ядра /etc/system. Для уточнения того, какие настройки требуются именно вашему программному обеспечению под Solaris , обратитесь к руководству по этому ПО.
Для Oracle8i в Oracle8i Installation Guide Release 3 рекомендуются следующие начальные значения параметров:
Значение seminfo_semmns рекомендуется установить равным сумме параметров PROCESSES всех баз данных сервера, причем самый большой из них должен быть просуммирован с коэффициентом 2, плюс еще 10 на каждую базу данных.
Посмотреть текущие значения параметров семафоров в Solaris до версии 9 включительно было можно по команде
Однако начиная с версии Solaris 10 для этого следует применять команду prctl, об использовании которой больше рассказывается в лекции 5 курса «Системное администрирование ОС Solaris 10».
Посмотреть текущие наборы семафоров в Solaris можно по команде
Иногда случается, что при неверном завершении процесса семафоры остаются блокированными. При этом может случиться, что повторный запуск интенсивно использующего семафоры процесса сорвется из-за нехватки семафоров. В этом случае необходимо удалить соответствующие наборы семафоров командой
semsetID здесь означает идентификатор набора семафоров .