Как мне узнать, выполняется ли исполняемый файл программы на C передним или задним планом? - PullRequest
4 голосов
/ 11 марта 2010

В моей программе на C я хочу знать, выполняется ли мой исполняемый файл на переднем плане, как это

$./a.out

или как это

$./a.out &

Ответы [ 5 ]

7 голосов
/ 11 марта 2010

Из Справочного руководства Bash: Основы управления заданиями :

Фоновые процессы - это те, чей идентификатор группы процессов отличается от идентификатора терминала; такие процессы неуязвимы для сигналов, генерируемых клавиатурой. Только приоритетные процессы могут читать или записывать в терминал. Фоновые процессы, которые пытаются прочитать (записать) на терминал, посылают сигнал SIGTTIN (SIGTTOU) драйвером терминала, который, если не перехватывается, приостанавливает процесс.

Таким образом, решение состоит в том, чтобы установить обработчик сигнала для SIGTTIN, а затем попытаться прочитать из stdin (отключите буферизацию, иначе она заблокируется). Если вы вернете «0 байт», значит, вы работаете на переднем плане.

[РЕДАКТИРОВАТЬ] Обратите внимание, что статус процесса может измениться. Для этого вы можете использовать команды управления заданиями оболочки (Ctrl-Z, bg, fg и jobs).

6 голосов
/ 11 марта 2010

Если вы на переднем плане,

getpgrp() == tcgetpgrp(STDOUT_FILENO)

или STDIN_FILENO или STDERR_FILENO или любой дескриптор файла, к которому вы подключены к своему управляющему терминалу. (Если вы не уверены, open("/dev/tty") всегда доставит вам файловый дескриптор на ваш управляющий терминал, если таковой существует.)

Это то, что делает openssh , и это немного проще, чем обработка SIGTTIN/SIGTTOU, если вы просто хотите быструю проверку.

С другой стороны, возможно, вы были на заднем плане

$ ./a.out
^Z
[1]+  Stopped                 ./a.out
$ bg
[1]+ ./a.out &

или прежде всего

$ fg
./a.out

в любой момент времени. Вы не можете ожидать, что сможете проверить это один раз, и это все равно будет верным (или ложным) позже.

1 голос
/ 11 марта 2010

Насколько мне известно, это невозможно и обычно тоже не нужно.

Пожалуйста, объясните , почему вы хотите это сделать.

0 голосов
/ 19 сентября 2014

Возможно, у вас более одного процесса работает в фоновом режиме:

$ jobs
[1]   Stopped                 teamviewer
[2]-  Stopped                 vim
[3]+  Stopped                 firefox
  • используйте: fg %2 для отправки процесса vim обратно на передний план.

  • Чтобы отправить последний процесс обратно на передний план, просто используйте: fg без аргументы.

  • Вы также можете ввести% process_name для возобновления остановленного процесса.

Чтобы приостановить процесс, работающий в фоновом режиме , используйте:

kill -19 %job_id.

Сигнал -19 - это SIGSTOP (сигнал посылается с помощью Ctrl - Z).

вы всегда можете увидеть список, набрав kill -l

Перемещение заданий между фоном / передним планом:

Если вы уже ввели команду и забыли использовать &, вы можете поместить задний план на задний план, набрав ^Z (CTRL-Z), чтобы приостановить задание, а затем bg, чтобы перевести его в фоновый режим. :

$ sleep 99
^Z
[1]+  Stopped                 sleep 99
$ bg
[1]+ sleep 99 &

Вы можете получить список заданий текущей оболочки, используя команду jobs.

Просто помните, что «выход из оболочки» также влияет на задания:

  • Задания, работающие в фоновом режиме, когда выходы из оболочки остаются работающими.
  • Задания, которые ставятся на паузу («Остановлено») при выходе из оболочки, прекращаются.

Отправка сигналов на задания и процессы

Вы можете отправлять сигналы, включая сигналы завершения, в задания, которые запускаются из текущей оболочки, используя номера заданий с использованием% (JOBID) вместо номеров процессов (PID):

$ kill %1
[1]+  Terminated              sleep 99

Чтобы отправлять сигналы процессам или заданиям, не запущенным из текущей оболочки, сначала необходимо использовать ps, чтобы найти их номера процессов (PID).

Вы можете обратиться по этой ссылке: процессы и задания

Общие команды управления заданиями в Linux:

  • jobs - список текущих работ
  • fg - возобновить работу, следующую в очереди
  • фг % [число] - возобновить работу [номер]
  • bg - Переместить следующее задание в очереди в фоновый режим
  • bg % [число] - отодвинуть задание [число] на задний план
  • kill % [число] - убить задание с номером [число]
  • kill - [signal]% [number] - отправить сигнал [signal] на номер задания [number]
  • disown % [число] - отключить процесс (терминал больше не будет владельцем), поэтому команда будет работать даже после закрытия терминала.

Это почти все из них. Обратите внимание на% infront номера задания в командах - это то, что говорит kill, вы говорите о заданиях, а не процессах.

0 голосов
/ 11 марта 2010

[неверно]
IIRC, getppid () (в * nix системах) даст вам родительский идентификатор. если это 0, «console» является вашим родителем, поэтому вы работаете в фоновом режиме.
[/ Недействительно]

[править]

int devtty;
if ((devtty = open ("/dev/tty", O_RDWR)) < 0)
   printf ("daemon\n");


обратите внимание, что это действительно только в * nix системах (и только в том случае, если по какой-либо причине никто не удалил / dev / tty) [/ Править]

...