Процеси, управление на задачите (Job control)
2. Създаване, управление и завършване (kill) на процеси
Пораждащ и породен процес (Parent and Child)
Команда top (table of processes)
Изпращане на сигнал – команда kill
В Unix / Unix задача (job) представлява група процеси. Базовите средства включват стартиране, спиране, рестартиране, завършване и прехвърляне на заден план (background) на процесите. По разширени функции за управление могат да бъдат извършвани чрез подаване на сигнали към процесите.
При отварянето на терминал потребителят притежава само един процес – командния интерпретатор. Повечето задачи - например стандартната Unix команда cat (concatenate files), се изпълняват чрез предаване на контрола от терминала на програмата, четене от стандартния вход, писане на стандартния изход, взимане на сигнали от клавиатурата (като сигнал за край потока – „Control+D“) и връщането на контрола на командния интерпретатор след края на програмата.
Понякога обаче потребителя иска да се изпълни някаква задача, докато използва терминала за нещо друго. Работеща задача, която не комуникира с терминала се нарича работеща на заден план (in the background), докато единствената задача комуникираща с терминала работи на преден план (in the foreground). Управлението на задачите предоставя средства за стартиране на процеси на заден план, изпращане на вече работещи процеси на заден план и обратно и прекратяване и завършване на процеси.
Понятието задача (job) се свързва с единична команда към интерпретатора, която стартира еди или повече процеси. Процесите могат да създават допълнителни породени (child) процеси. Единична команда може да стартира конвейер от процеси.
Управлението на задачите позволява на интерпретатора да управлява тези процеси като единна единица и например да спира изпълнението на цялата група с подходяща комбинация от клавиатурата (обикновено Control+Z).
Поставянето на “&” в края на командната линия стартира задачата на заден план. Ако задачата се нуждае от входна комуникация с обвивката (например stdin), изпълнението й се спира, но тя остава активна. Това не се отнася за stdout - задача работеща на заден план продължава да извежда съобщения към терминала, от който е извикана.
С комбинацията Ctrl+Z се спира изпълнението на задача работеща на преден план и се прекратява комуникацията й с командния интерпретатор. Задачата остава активна. Нейното изпълнение може да бъде рестартирано с извеждането й отново на преден план или с рестартирането й на заден план.
Спрените и работещите на заден план задачи получават номера на задачите в таблица на задачите.
Тези номера могат да бъдат подавани към вградените команди за управление на задачите.
Вградени команди за управление на задачите: jobs, fg, и bg
Вградената команда jobs извежда списък на активните задачи и техните номера. Преди да бъде демонстрирана ще стартирам няколко команди на заден план (всяка команда стартира отделна задача (job)- xeyes (A Graphical eyes, which follows the mouse movement), gnome-calculator, nano, след което ще стартирам команда ping на преден план, след което ще я спра (Stopped) и прехвърля на заден с Ctrl+Z :
·
$xeyes &
[1] 3622
$ gnome-calculator &
[2] 3623
$ nano test.txt &
[3] 3634
$ ping www.google.com
PING www.google.com (142.250.187.164) 56(84) bytes of data.
64 bytes from sof02s46-in-f4.1e100.net (142.250.187.164): icmp_seq=1
ttl=117 time=3.51 ms
64 bytes from sof02s46-in-f4.1e100.net (142.250.187.164): icmp_seq=2
ttl=117 time=4.65 ms
64 bytes from sof02s46-in-f4.1e100.net (142.250.187.164): icmp_seq=3
ttl=117 time=3.79 ms
64 bytes from sof02s46-in-f4.1e100.net (142.250.187.164): icmp_seq=4
ttl=117 time=4.02 ms
^Z
[3]-
Stopped
nano test.txt
[4]+
Stopped
ping www.google.com
$jobs
[1]
Running
xeyes &
[2]
Running
gnome-calculator &
[3]-
Stopped
nano test.txt
[4]+
Stopped
ping www.google.com
$
jobs -l
[1] 3622
Running
xeyes &
[2] 3623
Running
gnome-calculator &
[3]- 3634 Stopped (tty output) nano test.txt
[4]+ 3639
Stopped
ping www.google.com
imom@imom-VirtualBox:~$
· Номерата на задачите са указани с квадратни скоби, но когато трябва да се използват от команди fg и bg пред тях се поставя знак за процент - %, например %1.
· Задачите отбелязани с + и – освен с номерата си могат да бъдат използвани с „%+“ съответно с „%-„
o %+ е текущата задача - последната активна задача.
o %- е предпоследната активна задача.
· Извиква задача от заден план и я прави работеща на преден.
· Рестартира спряна (например с Ctrl+Z ) задача на преден план .
· „fg %1“ ще изведе на преден план задача номер 1.
· fg без параметри е еквивалентна на „fg %+“.
$ fg %+
ping www.google.com
64 bytes from ams15s29-in-f100.1e100.net (172.217.17.100): icmp_seq=4
ttl=117 time=3.23 ms
64 bytes from ams15s29-in-f100.1e100.net (172.217.17.100): icmp_seq=5
ttl=117 time=3.66 ms
64 bytes from ams15s29-in-f100.1e100.net (172.217.17.100): icmp_seq=6
ttl=117 time=5.67 ms
^Z
[4]+
Stopped
ping www.google.com
$
$
· Рестартира спряна задача, като я оставя да се изпълнява на заден план. Тя не може да комуникира с интерпретатора тъй като е на заден план, но ако няма нужда от тази комуникация се изпълнява.
· bg без аргументи работи върху текущата задача.
$ jobs
[1]
Running
xeyes &
[2]
Running
gnome-calculator &
[3]+
Stopped
nano test.txt
[4]-
Stopped
ping www.google.com
$ fg %1
xeyes
^Z
[1]+
Stopped
xeyes
$ jobs
[1]+
Stopped
xeyes
[2]
Running
gnome-calculator &
[3]-
Stopped
nano test.txt
[4]
Stopped
ping www.google.com
$ bg %1
[1]+ xeyes &
$ jobs
[1]
Running
xeyes &
[2]-
Running
gnome-calculator &
[3]+
Stopped
nano test.txt
[4]
Stopped
ping www.google.com
$
В примера се извежда на преден план работещата задача на заден xeyes, стартира след което задачата се спира с Ctrl+Z. Командата bg я рестартира, като я оставя на заден план.
· Ядрото разглежда всяка работеща програма като процес (running instance of a program).
· Процесът ‘lives’ докато се изпълнява с различно време на живот.
· Процесът умира ( ‘dies’) при завършването си.
· Ядрото идентифицира всеки процес чрез номер – идентификатор на процес (pid). Той може да бъде проверен чрез команда pidof
$ pidof bash
15170
$
·
Ядрото пази информация за различни
свойства на
всеки процес.
Процесите са свързани с контролиращия ги терминал. При затваряне на
терминала се унищожават свързаните с него процеси.
Съществуват процеси, наричани демони (daemon processes), които не
са свързани с терминал и са важни за функционирането на системата.
Стартират се при първоначалното зареждане на системата и
завършват при shutdown.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
fprintf(stdout,"printing from process_id(pid)=%d
\n",getpid());
// make two process which run same program after
fork();
pid_t p = fork();
if(p<0){
fprintf(stderr,"fork fail");
exit(1);
}
fprintf(stdout,"after fork()!, pid = %d ppid= %d
\n",getpid(),getppid());
return 0;
}
$ pidof init
1
$
o Всеки друг процес е породен от pid 1
o Дава моментна снимка на изпълняваните процеси в даден момент от време.
o Много гъвкава по отношение на количеството и начина на извеждане на показваната информация:
o Използвана без опции показва късо резюме за всеки процес
o Само процесите, които се притежават от текущия потребител и които за закачени за терминала
$ ps
PID TTY TIME CMD
25036 pts/8 00:00:00 bash
25471 pts/8 00:00:00 ps
$
PID: Идентификатор на процеса
TTY: терминал свързан с процеса
TIME: Общо използвано време от CPU
CMD: име на командата
o За съжаление приеманите опции не следват единен синтаксис а представляват смес от три синтаксиса :
o UNIX опции, които могат да бъдат групирани и се предхождат от тире.
o BSD опции, които могат да бъдат групирани и не се предхождат от тире.
o GNU дълги опции, които се предхождат от две тирета.
Различните опции могат свободно да бъдат смесвани, но има опасност от конфликти.
o ps има много опции
Някои от най-често използваните :
o a показва процесите използвани от други потребители
o f показва пораждащите процеси като дървовидна структура
$ bash
$ ps f
PID TTY STAT TIME COMMAND
25036 pts/8 Ss 0:00 -bash
25528 pts/8 S 0:00 \_ bash
25538 pts/8 R+ 0:00 \_ ps f
o u показва потребителите и кога е стартиран процеса (RSS - Resident Set Size, VSZ - Virtual Memory Size)
$ps u
USER PID %CPU
%MEM VSZ RSS
TTY STAT START TIME COMMAND
imom 15170 0.0 0.0
25328 5404 pts/0 Ss
06:52 0:00 -bash
imom 15468 0.2 0.0
25280 5268 pts/0 S
07:34 0:00 bash
imom 15477 0.0 0.0
39812 3460 pts/0 R+
07:35 0:00 ps u
$
o -e показва информация за всички процеси
o ps -e |grep ? показва информация за всички процеси не свързани с терминал
o -l допълнителна информация (в „дълъг“ формат)
ps -l
F S UID PID PPID C PRI NI
ADDR SZ WCHAN
TTY TIME CMD
0 S 1000 15170 15169 0 80 0 - 6332
wait pts/0 00:00:00 bash
0 S 1000 15468 15170 0 80 0 - 6320
wait pts/0 00:00:00 bash
0 R 1000 15650 15468 0 80 0 - 7839
- pts/0 00:00:00 ps
o -f използва пълен (full) формат
o -C cmd показва само процесите с име cmd
o -U user показва само процесите притежавани от user
Допълнителна информация може да се намери с
$man ps
Колоната STAT показва в какво състояние се намира процеса. Най-често срещаните кодове са:
R: running
S: прекъсваем sleep, чакащ някакво събитие (вход от терминал,
завършване на породен процес ...)
D: непрекъсваем sleep, процесът не може да бъде killed или
прекъснат чрез сигнал.
Z: Zombie
T: Stopped
В състоянието на процеса могат да се появят и допълнителни символи
< висок приоритет(not nice за другите
потребители)
N нисък приоритет (nice за другите потребители)
s лидер на сесията
l процесът е multi-threaded
+ процесът е в групата на преден план
Показва на пълен екран на терминала моментна снимка на активността на процесите. Снимката се обновява автоматично през къс период от време и създава илюзия за следене в реално време.
Процесите са подредени в низходящ ред, съобразно процента използвано време на процесора.
Показва също така информация за натоварването на системата.
Позволява въвеждането на интерактивни команди в процеса на изпълнение.
Пояснение на първите редове
Първи ред - top
Втори ред - Tasks
Трети ред - Cpu
Четвърти и пети ред - използвана памет
Повече по този въпрос може да се види тук
Пояснение за някои колони:
NI - Nice Value. Отрицателна стойност означава по-висок приоритет, а положителна - по-нисък.
RES - Resident Memory Size. Подмножество на виртуалното адресно пространство (VIRT) представляващо използваната резидентна памет.
Някои опции на командния ред:
-b Batch mode – изпраща снимките последователнона стандартния изход
-n num завършва след показването на num снимки
-d delay изчаква delay секунди между снимките
-i игнорира не ползващите ресурси (idle) процеси
-s забранява интерактивните команди (опасни ако се използват от супер-потребителя - superuser)
Интерактивни команди :
Key Behaviour
q Quit the program
Ctrl+L Repaint the screen
h Show a help screen
k Prompts for a pid and a signal, and sends that signal to that process
n Prompts for the number of processes to show information; 0 (the default) means to show as many as will fit
r Change the priority (‘niceness’) of a process
s Change the number of seconds to delay between updates. The number may include fractions of a second (0.5, for example)
Вградена команда, която се използва за извикване на команда или скрипт на обвивката с определен приоритет, давайки му повече или по-малко процесорно време спрямо другите процеси. За най-висок приоритет: -20, за най-нисък: 19. Подразбиращата стойност се наследява от пораждащия процес и обикновено е 0.
Например ако потребител желае да компресира голям файл, но не желае да забавя другите процеси:
$ nice -n 19 tar cvzf large_archived.tgz largefile
Опцията "c" изисква създаване на архив, опцията "v" (verbose) изисква операцията да извежда максимално информация, а опцията "f" има за аргумент името на архивата.
Приоритетът на работещ процес може да се сменя с команда "renice".
Usage:
renice [-n] <priority> [-p|--pid] <pid>...
renice [-n] <priority> -g|--pgrp <pgid>...
renice [-n] <priority> -u|--user <user>...
Alter the priority of running processes.
Options:
-n, --priority <num> specify the nice increment
value
-p, --pid
<id> interpret
argument as process ID (default)
-g, --pgrp <id>
interpret argument as process group ID
-u, --user <name>|<id> interpret argument as username
or user ID
Например командата:
$ renice +1 987 -u daemon root -p 32
Сменя приоритета на процеси с pid 987 и 32, както и на всички процеси със собственици daemon и root.
Сигналите са асинхронни предупреждения за важни събития изпращани към процесите (или задачите) от ядрото или от друг процес. Всеки сигнал е цяло число (1,2, …) с мнемонично име, което обикновено е дефинирано в файла /usr/include/signal.h. Те прекъсват дейността на процеса и го принуждават да ги обработи веднага.
Имената на сигналите са с главни букви и често включват SIG в името например SIGINT
Командата “kill –l“ извежда списъка на наличните в системата сигнали.
Име Номер Действие
SIGINT (или INT) 2 Прекъсване. Изпраща се от ядрото при въвеждане Ctrl+C на терминала.
SIGTERM (или TERM) 15 “Please terminate.” Заявка за нормално приключване на процеса.
SIGKILL (или KILL) 9 “Die!” Принуждава процеса да завърши без да му се дава възможност за нормална завършваща дейност.
SIGSTOP (или STOP) 19 Временно спира (suspend) действието на процеса. Изпраща се от ядрото при въвеждане Ctrl+Z на терминала.
SIGCONT (или CONT) 19 стартира отново спрян процес (resume)Временно прекратяв
SIGHUP 1 Hang up. Изпраща се от ядрото при отписване на потребителя. Използвано от демони като инструкция за презареждане на конфигурационните файлове.
Командата изпраща сигнал към процес (не само за завършване на процес). В много ядра командата е вградена. Сигналът се подава с опция –s ( която може да бъде пропусната).
Синтаксис: kill [ -s сигнал | -p ] pid...
Например сигналът SIGTERM може да се подаде по следните начини ( pid на процеса е '1234'):
$kill 1234
$kill -s TERM 1234
$kill -TERM 1234
$kill -15 1234
Сигналът SIGKILL може да бъде подаден по три начина:
$kill -s KILL 1234
$kill -KILL 1234
$kill -9 1234
Могат да бъдат указани няколко pid на процеси, към които да бъде подаден сигналът едновременно.
Пример. Ако трябва да бъде спрян и след това рестартиран процес (или задача) работещ в background може да се използва номерът на задачата или на процеса:
$xeyes &
[1] 9426
$ jobs -l
[1]+ 9426
Running
xeyes &
$ kill -STOP %1
$ jobs -l
[1]+ 9426 Stopped
(signal) xeyes
$ kill -CONT %1
$ jobs -l
[1]+ 9426
Running
xeyes &
$