Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Новый топик    Ответить
 Как принудительно завершить процесс  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
Запускаю программы через терминал
Do ^Programma1
Иногда запускаю программы через JOB
Все названия программ известны, могу через
  • $IO
  • $JOB
  • $Principal
  • $ZChild
узнать номер процесса каше (уникальный номер запущенного процесса) в виде |TRM|:|6900 или 6900

Имеется отдельная программа, которая ДОЛЖНА в случае сбоя отключать все запущенные процессы и завершить (мягко) работу.

Можно конечно в каждую программу встроить проверочный блок - что если с БД появилось сообщение (ключ) о завершении работы, то данные процессы самоликвидируются через "HALT" (обращается к глобальной переменной, в которой указано что нужно прекратить работу).
Проблема в том, что при большой нагрузке, начинаются сбои и ошибочно вылазит код о принудительном завершении. Редко, но все же.

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

Запустил в терминале программу
do ^Start1
do ^Start2
do ^StopProgramm
Что должно быть в коде, чтобы выключить, остановить, завершить выполнение программ ^Start1, ^Start2 ?
Можно завершить жестко, остальное доделывает ^StopProgramm.

Если у вас есть код больше двух строк (с наворотами), то буду работать по старинке (через обращение к переменной в БД).
Ищу простое решение.
29 мар 16, 17:26    [18992559]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
Нужно, чтобы программа не самоликвидировалась, а чтобы её остановила, прервала другая ВНЕШНЯЯ программа.
29 мар 16, 17:35    [18992608]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
DAiMor
Member

Откуда: Volzhsky -> Moscow -> CZ, Brno -> Moscow
Сообщений: 2633
О-О-О,

$system.Process.Terminate(pid)
или
$zu(4,pid)
29 мар 16, 17:44    [18992645]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
DAiMor
О-О-О,

$system.Process.Terminate(pid)
или
$zu(4,pid)
C первым вариантом прошло на ура, а вот второй вариант - работать не хочет.

Разобрался.
Если написать
do $zu(4,6756)
где 6756 - это номер запущенного процесса, то тогда также закрывается

DO $SYSTEM.Process.Terminate(6756)

Равнозначны

Спасибо, DAiMor.
Вопросов больше нет.
29 мар 16, 17:59    [18992737]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1547
Всё не так однозначно.
Случай из жизни: процесс мог работать очень долго, но иногда надо было его прибить (для прекращения обслуживания некоего оборудования). Но процесс мог упасть и сам из-за ошибки. Так вот на нагруженном сервере 5-ти значный номер процесса мог повториться достаточно быстро (в течение суток), поэтому знать номер процесса оказалось мало, пришлось проверять переменную процесса и прибивать его, лишь если ей присвоено правильное значение.
29 мар 16, 21:51    [18993606]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
misha_shar
Member

Откуда: Казахстан город Алма-Ата
Сообщений: 164
Alexey Maslov
Всё не так однозначно.
Случай из жизни: процесс мог работать очень долго, но иногда надо было его прибить (для прекращения обслуживания некоего оборудования). Но процесс мог упасть и сам из-за ошибки. Так вот на нагруженном сервере 5-ти значный номер процесса мог повториться достаточно быстро (в течение суток), поэтому знать номер процесса оказалось мало, пришлось проверять переменную процесса и прибивать его, лишь если ей присвоено правильное значение.

Чтобы управлять процессами во внешней программе необходимо вести Pidы запущенных процессов и если появился дубликат, то предыдущий процесс уже удален и значит по нему никаких действий предпринимать не надо.
30 мар 16, 06:04    [18994097]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
Alexey Maslov
Всё не так однозначно.
Случай из жизни: процесс мог работать очень долго, но иногда надо было его прибить (для прекращения обслуживания некоего оборудования). Но процесс мог упасть и сам из-за ошибки. Так вот на нагруженном сервере 5-ти значный номер процесса мог повториться достаточно быстро (в течение суток), поэтому знать номер процесса оказалось мало, пришлось проверять переменную процесса и прибивать его, лишь если ей присвоено правильное значение.
Вот этот вопрос у меня сегодня и возник утром.
Как узнать перечень ВСЕХ запущенных процессов с их ИМЕНЕМ и НОМЕРОМ PID, чтобы затем, можно было вручную поотключать их.
Как на снимке

Alexey Maslov, ваше решение проблемы было бы интересно (опять ищу функцию, которая бы выводила список всех запущенных процессов с их именами и PID-ами).

P.S.
Кстати, $ZU очень интересная/занимательная функция.
30 мар 16, 08:03    [18994162]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
Снимок

К сообщению приложен файл. Размер - 134Kb
30 мар 16, 08:04    [18994164]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
Кстати, по моим соображениям,
Получение списка всех запущенных процессов существенно распараллеливает процессы.
К примеру, нужно вывести несколько графиков в один отчет.
Каждый выводится от 3 до 7 сек, причем всегда по разному. Обычно, я не замарачиваюсь и запускаю их последовательно. Получается примерно 15 сек на один отчет. Все графики выводятся по одной анализируемой дате. Таких дат за раз около 180-250.
Если же знать номер процесса и его название, то можно задать генерацию графиков одновременно и опрашивать запущенные процессы. После генерации PDF отчета с графиками, программа завершает работу через Halt.
Итого в остатке получаем - как только в списке запущенных процессов не осталось запущенных программ по генерации графиков, можем запускать следующий цикл по генерации отчетов PDF с графиками.

Ориентировочное время сокращение работы уменьшится с 15 сек до 5-6 секунд.
Наверняка у многих периодически возникают такие задачи (генерации отчетов по одним данным) и затем генерация следующего отчета (после успешной генерации предыдущего отчета). А это возможно только при последовательном выполнении отчетов, программы, чтобы не запустить процесс генерации нового отчета раньше времени.
30 мар 16, 08:18    [18994183]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
CacheUK
Guest
О-О-О, Мы запускаем программу в Job-е. Чтобы узнать PID процесса, в котором она исполняется используем код:
 zn "%SYS"
 
Set rs ##class(%ResultSet).%New()
 
rs.Prepare("Select Pid,Routine from %SYS.ProcessQuery where Routine='MyProgName'")
 
rs.Execute()
 
While rs.Next(){
  
set PidS=rs.Pid  // номер процесса, в котором работает программа ^MyProgName
 
}
 
do rs.Close()
 
zn "workns"
Дальше с эти процессом делайте то, что Вам нужно.
30 мар 16, 08:34    [18994213]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
CacheUK,

Спасибо.
То что нужно. Направление понял.
Ваш код сработал без запинок.

Если указать
Process=##CLASS(%SYS.ProcessQuery).Open("J14")
то будет выведен процесс под номером 14 (самый первый столбец #Job). Здесь уже идёт нумерация подряд и без дырок в нумерации.
Не путать нумерацию Pid (где каше выдаёт случайное число) и нумерацию кол-ва запущенных процессов (Job).
Таким способом можно перебрать все существующие процессы, запущенные в Cache.

Более подробно %SYS.ProcessQuery
30 мар 16, 09:22    [18994286]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3117
Блог
О-О-О
Нужно, чтобы программа не самоликвидировалась, а чтобы её остановила, прервала другая ВНЕШНЯЯ программа.
Было: 9162920, 6973280
О-О-О
P.S.
Кстати, $ZU очень интересная/занимательная функция.
Которой не следует пользоваться.
О-О-О
Как узнать перечень ВСЕХ запущенных процессов с их ИМЕНЕМ и НОМЕРОМ PID, чтобы затем, можно было вручную поотключать их.
Документация
For other aspects of process management, refer to the %SYS.ProcessQuery class.

Process Management

PS: ещё может пригодиться останов зависших процессов: $SYSTEM.Util.CleanDeadJobs().
30 мар 16, 09:27    [18994299]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
eduard93
Member

Откуда:
Сообщений: 167
О-О-О
Кстати, по моим соображениям,
Получение списка всех запущенных процессов существенно распараллеливает процессы.
К примеру, нужно вывести несколько графиков в один отчет.
Каждый выводится от 3 до 7 сек, причем всегда по разному. Обычно, я не замарачиваюсь и запускаю их последовательно. Получается примерно 15 сек на один отчет. Все графики выводятся по одной анализируемой дате. Таких дат за раз около 180-250.
Если же знать номер процесса и его название, то можно задать генерацию графиков одновременно и опрашивать запущенные процессы. После генерации PDF отчета с графиками, программа завершает работу через Halt.
Итого в остатке получаем - как только в списке запущенных процессов не осталось запущенных программ по генерации графиков, можем запускать следующий цикл по генерации отчетов PDF с графиками.

Ориентировочное время сокращение работы уменьшится с 15 сек до 5-6 секунд.
Наверняка у многих периодически возникают такие задачи (генерации отчетов по одним данным) и затем генерация следующего отчета (после успешной генерации предыдущего отчета). А это возможно только при последовательном выполнении отчетов, программы, чтобы не запустить процесс генерации нового отчета раньше времени.
Для достижения этого эффекта можно и даже нужно использовать события. Вот минимальный пример кода:
Class Utils.Job
{

/// do ##class(Utils.Job).PrintParralelWS()
ClassMethod 
PrintParralelWS(JobCount As %Integer 4Timeout As %Integer 1)
{
  
 
write "Start",!
 
for i=1:1:JobCount {
   
job ..exec1(Timeout)
 
}
 
write "All jobs started",!
 
for i=1:1:JobCount {
   
set msg $listget($system.Event.WaitMsg(), 2)
   
write msg,!
 
}
 
write "All jobs complete"
}

ClassMethod exec1(Timeout As %Integer 1)
{
 
hang Timeout
 
do $system.Event.Signal($zparent"Job " $job " complete")
}

}
Метод do ##class(Utils.Job).PrintParralelWS() будет выполняться примерно 1 секунду.
Более развёрнутые примеры выложены на GitHub тут и тут. Также есть обсуждение на community портале InterSystems.
30 мар 16, 11:18    [18994707]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3117
Блог
eduard93
Более развёрнутые примеры выложены на GitHub тут и тут. Также есть обсуждение на community портале InterSystems.
И даже тут (17624921) и тут (13880300), причём на русском, чего очень бы хотелось и от ветки intersystems-ru.
30 мар 16, 11:32    [18994794]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
eduard93
Member

Откуда:
Сообщений: 167
servit
причём на русском, чего очень бы хотелось и от ветки intersystems-ru.

Несмотря на название у нас там всё-таки международное комьюнити, так что английский язык выбран выбран в качестве основного при написании кода/комментариев.
30 мар 16, 12:37    [18995214]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3117
Блог
eduard93
servit
причём на русском, чего очень бы хотелось и от ветки intersystems-ru.
Несмотря на название у нас там всё-таки международное комьюнити, так что английский язык выбран выбран в качестве основного при написании кода/комментариев.
К коду/комментариям вопросов нет и не было, а вот описания, инструкции, возможно и документацию, хотелось бы видеть в том числе и на русском, как это сделано у других:
PS: впрочем, нет так нет.
30 мар 16, 13:01    [18995355]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3117
Блог
eduard93,

А ведь был же русский когда-то:
30 мар 16, 13:11    [18995420]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
eduard93
Member

Откуда:
Сообщений: 167
servit
eduard93,

А ведь был же русский когда-то:

А это и сейчас бывает. Все страницы вики проекта MDX2JSON (кроме примеров вывода) полностью доступны как на английском так и на русском языках.
30 мар 16, 14:10    [18995784]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3117
Блог
eduard93
А это и сейчас бывает.
Вот именно, что бывает.

PS: что ж, бывает.
30 мар 16, 14:25    [18995913]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1547
О-О-О
Alexey Maslov, ваше решение проблемы было бы интересно
Номера процессов были известны из $zchild (все они были JOB-нутыми) и сохранялись в глобале, поэтому получение их списка с PID и т.д. не требовалось.
Проблема состояла в том, как достоверно узнать, является ли процесс с известным номером (PID) тем самым процессом, который мы когда-то запустили для решения определённой задачи, или его номер случайно совпал с номером "нашего" процесса (а наш аварийно завершился). Определить это по имени программы было нельзя, т.к. одна и та же программа могла использоваться в различных процессах. Поэтому остановились на запросе значения переменной с известным именем у процесса с известным PID, для чего вполне подошёл запрос VariableByPid класса %SYS.ProcessQuery.
30 мар 16, 14:36    [18995992]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
О-О-О
Member

Откуда: Нижний Новгород
Сообщений: 211
Alexey Maslov,

Я так же хотел пойти по вашей схеме - при запуске программы записывать в глобал название программы и его PID. В моём случае - проще, т.к. программы запускаются утром а отключаются часов с 16 до 20 вечера.
Alexey Maslov
Поэтому остановились на запросе значения переменной с известным именем у процесса с известным PID, для чего вполне подошёл запрос VariableByPid класса %SYS.ProcessQuery.
Имеете ввиду, что даже связка PID+имя процесса не даёт уникальность. В результате чего потребовалась третья переменная. Типа внутри процесса висит переменная доступная для внешних программ (типа Public) и при её опросе - если она та самая - глушите, убиваете процесс "имя_процесса+PID+значение_переменной_из_имя_запущенной_программы".

Никогда с таким решением не сталкивался. Картинка с другого сайта.
Есть повод подумать на будущее.

Честно говоря даже не ожидал такого количества решений.
Мне в принципе подойдет любое из предложенных решение, т.к. одновременно запущенных процессов от 45 до 80, а с таким количеством вариантов справится любой из предложенных вариантов.
Буду взвешивать плюсы и минусы
P.S. Об "Аварийное завершение программ" и дальнейшем их "зависании" в списке PID даже не задумывался. Так что этот вариант точно придётся брать в расчёт.

Всем спасибо.
30 мар 16, 18:05    [18997227]     Ответить | Цитировать Сообщить модератору
 Re: Как принудительно завершить процесс  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1547
О-О-О
Никогда с таким решением не сталкивался.
Благодаря вам задумался: зачем было делать так сложно?

Не я был автором прикладного кода, лишь придумал способ проверки "свой-чужой" и реализовал её в виде метода, который проверяет живость процесса и возвращает значение заданной переменной. Проверяемый процесс может быть запущен либо локально, либо на сервере данных ECP.

Однако гораздо проще было написать код для JOB^%ZSTOP, в котором всего-навсего удалять:
Kill ^MyProcessTable($job)
Тогда "глобальная" таблица процессов обновлялась бы динамически, и не требовалось бы лазить в чужую память (что, кстати, требует некоторого повышения полномочий).
30 мар 16, 19:34    [18997624]     Ответить | Цитировать Сообщить модератору
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Ответить