powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Выйти из консольного приложения Linux правильно
13 сообщений из 13, страница 1 из 1
Выйти из консольного приложения Linux правильно
    #39635473
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В начале было слово)
В начале было так

Код: 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
Выйти из консольного приложения Linux правильно
    #39635484
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Выйти из консольного приложения Linux правильно
    #39635559
rashid.abzalov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

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

Возможно стоит посмотреть в сторону pthread_sigmask(SIG_BLOCK, ... и sigwait.
...
Рейтинг: 0 / 0
Выйти из консольного приложения Linux правильно
    #39635793
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.
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
Выйти из консольного приложения Linux правильно
    #39636287
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Выйти из консольного приложения Linux правильно
    #39636519
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Выйти из консольного приложения Linux правильно
    #39636837
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrb,

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

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

Если SIGINT ловишь под отладчиком, то там баг - RSP-18540 . Без отладчика все ловится нормально.
...
Рейтинг: 0 / 0
Выйти из консольного приложения Linux правильно
    #39671408
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rashid.abzalov, точно. Спасибо. Действительно под отладчиком не срабатывает, а если запускать отдельно, то все хорошо.
...
Рейтинг: 0 / 0
Выйти из консольного приложения Linux правильно
    #39741847
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.
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
Выйти из консольного приложения Linux правильно
    #39741896
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
работа с сигналами в paserver в режиме отладки не исправлена в 10.2.3. В релизе все работает штатно.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Выйти из консольного приложения Linux правильно
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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