Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Выйти из консольного приложения Linux правильно / 13 сообщений из 13, страница 1 из 1
24.04.2018, 15:18
    #39635473
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
В начале было слово)
В начале было так

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
begin
try 
Writeln('началось...');
    StartService;
    Writeln('Для остановки приложения нажмите <Enter>...');
    Readln;
    StopService;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
end;



Запускалось приложение, запускались потоки, ждали в консоли Enter, завершали потоки.
Потом задача усложнилась и мне стало нужно проверять пару параметров (если вдруг аварийное завершение работы)

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
try
    Writeln('началось');
    StartService;
    Writeln('Для остановки приложения нажмите <Ctrl+C>...'); //<Enter>
//    Readln;
    while (err_1 = 0) and (err_2 = 0) and (ERR_3 = 0) do
    begin
      sleep(1000);
    end;
    StopService;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;



Подскажите, есть readConsoleInput - можно отслеживать для Windows, а как быть для Linux?
...
Рейтинг: 0 / 0
24.04.2018, 15:41
    #39635484
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
cptngrbПодскажите, есть readConsoleInput - можно отслеживать для Windows, а как быть для Linux?

Код: sql
1.
2.
sigaction(SIGTERM, &act, NULL); (* software termination signal from kill *)
sigaction(SIGINT, &act, NULL); (* Ctrl-C pressed *)


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
24.04.2018, 17:51
    #39635559
rashid.abzalov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
Dimitry Sibiryakov,

Если в Delphi (не знаю как в fpc), то номер может не выйти, т.к. в System.Internal.ExcUtils.pas уже назначен обработчик SignalDispatcher для сигналов на которых строится механика RTL для отлова и обработки hardware-ошибок.

Возможно стоит посмотреть в сторону pthread_sigmask(SIG_BLOCK, ... и sigwait.
...
Рейтинг: 0 / 0
25.04.2018, 08:14
    #39635793
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
немного покопался, почитал. получается что-то типа такого, но сигнал не ловиться

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
uses Posix.Signal;

procedure SignalHandler(SigNum: Integer); cdecl;
begin
  WriteLn('SigNum (', SigNum, ') arrived.');
  case SigNum of
    SIGTERM, SIGINT: APP_EXIT:= 1;
  else
    WriteLn('SigNum (', SigNum, ') not handled.');
  end;
  Signal(SigNum, @SignalHandler); // catch the signal again
end;

begin
 
  try
    Writeln('началось...');
    StartService;
    Writeln('Для остановки приложения нажмите <Ctrl+C>...');
//    Readln;
    while (err_1 = 0) and (err_2 = 0) and (ERR_3 = 0) do
    begin
      Signal(SIGINT, @SignalHandler);
      sleep(1000);
    end;
    StopService;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.



нашел еще вариант, тоже не ловиться

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
procedure SignalSet(aProc : TSignalHandler);
var
  smask: sigset_t;
  act: sigaction_t;
begin
  sigemptyset(smask);
  sigaddset(smask,SIGINT);
  sigaddset(smask,SIGTERM);
  act._u.sa_handler := aProc;
  act.sa_mask := smask;
  act.sa_flags := 0;

  sigaction(SIGINT, @act, nil);
  sigaction(SIGTERM, @act, nil);
end;
...
Рейтинг: 0 / 0
25.04.2018, 18:05
    #39636287
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
cptngrb,

У себя ловлю сигналы так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
procedure DoSig(signal: longint; info: psiginfo; context: psigcontext); cdecl;
 begin
  case signal of
   //SIGHUP : bHup := true;
   SIGTERM: Prg.Terminate;
   SIGSTOP: Prg.Terminate;
  end;
 end;

 function SignalSet: longint;
 var
  smask: TSigset;
  act: sigactionrec;
 begin
  Result := 0;
  (* Signal mask setting *)
  FpsigEmptySet(smask);
  FpSigAddSet(smask, SIGSTOP);
  FpSigAddSet(smask, SIGTERM);
  act.sa_handler := SigactionHandler(@DoSig);
  act.sa_mask  := smask;
  act.sa_flags := 0;
  (* Signal exit function registered *)
  if FPSigaction(SIGSTOP, @act, nil) <> 0 then
   Result := fpgeterrno;
  if FPSigaction(SIGTERM, @act, nil) <> 0 then
   Result := fpgeterrno;
 end;
...
Рейтинг: 0 / 0
26.04.2018, 08:19
    #39636519
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
makhaon, а что такое psiginfo, psigcontext?
А это
Код: pascal
1.
2.
3.
4.
5.
6.
FpsigEmptySet(smask);
  FpSigAddSet(smask, SIGSTOP);
  FpSigAddSet(smask, SIGTERM);
  act.sa_handler := SigactionHandler(@DoSig);
  act.sa_mask  := smask;
  act.sa_flags := 0;



тоже самое как

Код: pascal
1.
2.
3.
4.
5.
6.
 sigemptyset(smask);
  sigaddset(smask,SIGINT);
  sigaddset(smask,SIGTERM);
  act._u.sa_handler := aProc;
  act.sa_mask := smask;
  act.sa_flags := 0;



только процедур нет FpsigEmptySet , FpSigAddSet .
может модуль какой не подключил или это не Delphi (в моем случае Tokyo 10.2)?
...
Рейтинг: 0 / 0
26.04.2018, 15:56
    #39636837
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
cptngrb,

FPC
...
Рейтинг: 0 / 0
06.07.2018, 11:56
    #39670601
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
Добрались руки до теста..
Сигнал SIGTERM ловиться если завершить процесс через диспетчер задач, а вот сигнал SIGINT не ловиться, если в консоле нажать <Ctrl-C>.
А мне более важно ловить SIGINT. Причем консоль закрывается, а процесс остается.
Объясните, как так?

P/S Линукс для меня шайтанОС
...
Рейтинг: 0 / 0
06.07.2018, 12:04
    #39670605
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
SIGTSTP ловить из диспетчера задач, а из консоли нет ((
короче из консоли ничего не ловиться, может другие сигналы?
...
Рейтинг: 0 / 0
06.07.2018, 19:37
    #39670871
rashid.abzalov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
cptngrb,

Если SIGINT ловишь под отладчиком, то там баг - RSP-18540 . Без отладчика все ловится нормально.
...
Рейтинг: 0 / 0
09.07.2018, 09:41
    #39671408
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
rashid.abzalov, точно. Спасибо. Действительно под отладчиком не срабатывает, а если запускать отдельно, то все хорошо.
...
Рейтинг: 0 / 0
03.12.2018, 09:48
    #39741847
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
Сигналы ловятся, но... я не успеваю корректно все очистить.
Может сигнал нужно поймать, а ОС его каким-то образом не дать принять ?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
{$IFDEF LINUX}
procedure SignalSet(aProc : TSignalHandler);
var
  smask: sigset_t;
  act: sigaction_t;
begin
  sigemptyset(smask);
  sigaddset(smask,SIGINT);
  sigaddset(smask,SIGTERM);

  act._u.sa_handler := aProc;
  act.sa_mask := smask;
  act.sa_flags := 0;

  sigaction(SIGINT, @act, nil);
  sigaction(SIGTERM, @act, nil);
end;

//ловит сигналы из диспетчера задач
procedure SignalHandler(SigNum: Integer); cdecl;
begin
  case SigNum of
    SIGTERM, SIGINT, SIGHUP, SIGTSTP: APP_EXIT:= 1;
  end;
end;
{$ENDIF}

begin
  {$IFDEF DEBUG}
  ReportMemoryLeaksOnShutdown := True;
  {$ENDIF}
  IsMultiThread := True;
  try
    StartService;
    {$IFDEF DEBUG} Writeln('Для остановки приложения нажмите <Enter>...');
    {$ELSE} Writeln('Для остановки приложения нажмите <Ctrl+C>...');
    {$ENDIF}

    Readln;
    {$IFDEF LINUX}SignalSet(SignalHandler); {$ENDIF}
    //{$IFDEF RELEASE}
    while (SERVICE_STOP = 0) and (APP_EXIT = 0) do
    begin
      Sleep(1000);
    end;
    //{$ENDIF}
    StopService;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.



В процедуре StopService ; идет остановка потоков и в ней появляется ошибка на переменную (динамический массив потоков), которая станет nil еще не скоро.
Причем, если использовать выход без ловли сигнала (в моем случае в debug версии), то все работает корректно.
...
Рейтинг: 0 / 0
03.12.2018, 12:17
    #39741896
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выйти из консольного приложения Linux правильно
работа с сигналами в paserver в режиме отладки не исправлена в 10.2.3. В релизе все работает штатно.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Выйти из консольного приложения Linux правильно / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]