КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
ДОДАТОК 2. Контроль над процесами ⇐ ПредыдущаяСтр 5 из 5
Кожна розпочата програма називається процесом. Ці процеси сягають від Віконної Системи X до системних програм (демонів), запущених під час старту системи. Кожний процес діє від імені певного користувача, ті що започатковано під час завантаження системи, як правило, запущені від імені root або nobody. Процеси, які ви розпочали, будуть числитись під вашим іменем. Вам надається повний контроль над процесами, що ви започаткували, root користувачу — над всіма процесами, інших користувачів включно. Контроль над процесами і спостереження здійснюється за допомогою декількох програм і команд оболонки, розглянутих нижче. Фонові процеси Програми, запущені з командного рядка, як правило, залишаються на передньому плані. Це дозволяє бачити весь вивід програми і взаємодіяти з нею. Тим не менш, часто буває, що нам необхідно розпочати програму таким чином, щоб вона не блокувала нашого терміналу, тобто у фоновому режимі. Існує декілька способів добитися цього. Під час запуску програми можна добавити знак кон'юнкції (&) в кінці командного рядка. Наприклад, ви вирішили використати програму amp(1) для того щоб прослухати каталог із mp3-файлами, але, одночасно, вам потрібен командний рядок для виконання інших завдань. Наступна команда запустить amp у фоновому режимі: $ amp *.mp3 &Іншим способом помістити програму у фоновий режим, це запустити її звичайно на передньому плані, тобто у пріоритетному режимі, потім притиснути комбінацію клавіш Ctrl+Z, яка призупиняє процес. Хоча процес і призупинено, його завжди можна знову запустити з того самого місця де його було перервано. Існує дві команди для цього: fg (скорочення для foreground) і bg (background). Щоб перезапустити процес у фоновому режимі, ми повинні виконати [1]+ Stopped amp *.mp3$ bgТепер колишній процес переднього плану буде виконуватись у фоновому режимі. Пріоритетні процеси Як ми вже сказали, запуск програми без амперсанду (знака кон'юкції) залишить її на передньому плані. Якщо ж ви загнали процес у фоновий режим за допомогою одного з способів, перелічених у попередньому розділі, то можете видобути його на передній план командою $ fgЯкщо процес дійсний, він візьме контроль над вашим терміналом. Іноді програми завершують свою роботу у фоновому режимі, у таких випадках ви отримаєте повідомлення на зразок: [1]+ Done amp *.mp3Цілком можливо мати декілька процесів, запущених у фоновому режимі, одночасно. У таких випадках потрібно знати, який саме процес вивести назовні, сама по собі команда fg виведе на передній план лише останню команду, що було загнано у фоновий режим, це може бути не тим, що нас цікавить. Нам потрібно спочатку перечислити всі процеси у підгрунтті за допомогою вбудованої bash-команди jobs: $ jobs[1] Stopped vim[2]- Stopped amp[3]+ Stopped man psУ цьому прикладі показано перелік процесів у фоновому режимі. Як ви бачите, вони всі позначені як "Stopped", тобто призупинені. Числа у квадратних дужках, це своєрідний ідентифікаційний номер процесів. Процес із знаком плюс (+) буде саме тим процесом, що звичайна fg виведе назовні. Щоб вивести якийсь інший з перечислених процесів, добавте ідентифікаційний номер після команди fg, наприклад для vim: $ fg 1Запуск програм у фоновому режимі дуже зручний у випадку ssh-з'єднань або використанню терміналів через даялап з'єднання, тощо. Ви можете запустити декілька програм одночасно і переходити від однієї до іншої у разі потреби. Ps Крім процесів, запущених вами з командного рядка, існують також багато додаткових, включаючи постійні системні процеси. Команда ps(1) допоможе перелічити всі процеси, включаючи ті що не належать вам. Ця команда має багато додаткових опцій, ми розглянемо найважливіші. Для повного списку загляніть у сторінку посібника ps(1). Сама по собі <tt>ps виведе список програм, запущених у поточному терміналі, включаючи пріоритетні процеси (разом із оболонкою, яку ви використовуєте і, звичайно, саму ps), фонові процеси також будуть перечислені. Частіше, це буде доволі коротким списком: $ ps PID TTY TIME CMD 7923 ttyp0 00:00:00 bash 8059 ttyp0 00:00:00 psОстаннє є доволі типовим виводом команди ps. Розглянемо, що ці поля виводу означають. PID (process ID) — кожному запущеному процесові надається унікальне ідентифікаційне число у діапазоні між 1 і 32767. Кожний процес, що започатковано отримає наступний вільний PID-номер. Якщо процес припиняє свою роботу або його вбито (дивіться kill команду у наступному підрозділі), він звільняє свій PID-номер. Коли досягнуто максимальної кількості номерів PID, призначення починається з нижчих звільнених чисел. TTY-стовпчик вказує на якому терміналі запущено процес. Звичайна команда ps перечислить лише процеси, запущені на поточному терміналі, тож всі процеси містять ту саму інформацію у нашому прикладі у стовпчику TTY, тобто ttyp0 (цей термінал призначено для віддалений під'єднань або X-емуляторів терміналу). TIME-стовпчик вказує скільки CPU-часу процес спожив. Цей час відрізнятиметься від фізичного часу. Пам'ятаймо, що Лінукс — це багатозадачна операційна система, багато процесів запущено водночас, кожному з яких може бути виділена лише маленька частка процесорного часу. Тож TIME-колонка покаже дійсний час, виділений процесором для окремих завдань. Якщо час у цій колонці перевищуватиме декілька хвилин, це може означати, що щось негаразд. Накінець, CMD-колонка вказує на саму програму. Виводиться лише базова назва програми, без командних опцій і аргументів. Для того щоб отримати цю додаткову інформацію, вам необхідно буде вжити деякі додаткові прапорці ps, розглянуті нижче. Ви можете отримати повний список процесів, запущених на вашій системі, за допомогою додаткових -ax або ax (без дефісу) опцій до ps, як показано у наступному прикладі (ми дещо скоротили вивід): $ ps -ax PID TTY STAT TIME COMMAND 1 ? S 0:03 init [3] 2 ? SW 0:13 [kflushd] 3 ? SW 0:14 [kupdate] 4 ? SW 0:00 [kpiod] 5 ? SW 0:17 [kswapd] 11 ? S 0:00 /sbin/kerneld 30 ? SW 0:01 [cardmgr] 50 ? S 0:00 /sbin/rpc.portmap 54 ? S 0:00 /usr/sbin/syslogd 57 ? S 0:00 /usr/sbin/klogd -c 3 59 ? S 0:00 /usr/sbin/inetd 61 ? S 0:04 /usr/local/sbin/sshd 63 ? S 0:00 /usr/sbin/rpc.mountd 65 ? S 0:00 /usr/sbin/rpc.nfsd 67 ? S 0:00 /usr/sbin/crond -l10 69 ? S 0:00 /usr/sbin/atd -b 15 -l 1 77 ? S 0:00 /usr/sbin/apmd 79 ? S 0:01 gpm -m /dev/mouse -t ps2 106 tty1 S 0:08 -bash 108 tty3 SW 0:00 [agetty] 109 tty4 SW 0:00 [agetty] 110 tty5 SW 0:00 [agetty] 111 tty6 SW 0:00 [agetty]...Ваш вивід може відрізнятися, в залежності від того які сервіси у вас запущені. Як бачите, деякі процеси показані з опціями командного рядка, тоді як інші мають опції прихованими (завдяки ptrace латці ядра, що приховує командні опції певних процесів). Як ви, напевне, зауважили, для багатьох процесів у TTY-стовпчику вказано "?". Це означає що ці процеси не прив'язано до жодного терміналу. Це характерно для демонів, — сервісів, що виконуються у фоновому режимі. Найпоширенішими демонами є sendmail, BIND, Apache (httpd), NFS, cron, тощо. Як правило, останні очікують запитів від клієнтів і повертають характерну інформацію якщо запит здійснено. Тут ми побачимо додаткову колонку під назвою STAT. STAT є скороченням від status (статус). Умовними позначеннями для статусів процесів є:
Якщо ви хочете отримати навіть більше інформації про процеси, спробуйте наступне: $ ps -aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 344 80 ? S Mar02 0:03 init [3] root 2 0.0 0.0 0 0 ? SW Mar02 0:13 [kflushd] root 3 0.0 0.0 0 0 ? SW Mar02 0:14 [kupdate] root 4 0.0 0.0 0 0 ? SW Mar02 0:00 [kpiod] root 5 0.0 0.0 0 0 ? SW Mar02 0:17 [kswapd] root 11 0.0 0.0 1044 44 ? S Mar02 0:00 /sbin/kerneld root 30 0.0 0.0 1160 0 ? SW Mar02 0:01 [cardmgr] bin 50 0.0 0.0 1076 120 ? S Mar02 0:00 /sbin/rpc.port root 54 0.0 0.1 1360 192 ? S Mar02 0:00 /usr/sbin/sysl root 57 0.0 0.1 1276 152 ? S Mar02 0:00 /usr/sbin/klog root 59 0.0 0.0 1332 60 ? S Mar02 0:00 /usr/sbin/inet root 61 0.0 0.2 1540 312 ? S Mar02 0:04 /usr/local/sbi root 63 0.0 0.0 1796 72 ? S Mar02 0:00 /usr/sbin/rpc. root 65 0.0 0.0 1812 68 ? S Mar02 0:00 /usr/sbin/rpc. root 67 0.0 0.2 1172 260 ? S Mar02 0:00 /usr/sbin/cron root 77 0.0 0.2 1048 316 ? S Mar02 0:00 /usr/sbin/apmd root 79 0.0 0.1 1100 152 ? S Mar02 0:01 gpm chris 106 0.0 0.5 1820 680 tty1 S Mar02 0:08 -bash root 108 0.0 0.0 1048 0 tty3 SW Mar02 0:00 [agetty] root 109 0.0 0.0 1048 0 tty4 SW Mar02 0:00 [agetty] root 110 0.0 0.0 1048 0 tty5 SW Mar02 0:00 [agetty] root 111 0.0 0.0 1048 0 tty6 SW Mar02 0:00 [agetty]...Останнє додасть також інформацію про те, який саме користувач започаткував процес, яку долю системних ресурсів процес використовує (%CPU, %MEM, VSZ та RSS колонки), також дату коли процес було започатковано. Очевидно, що це достатньо інформації, цікавої системному адміністраторові. Може статися, що виведені рядки будуть занадто довгі і вийдуть за рамки екрану, в такому випадку можна вжити також ключ -w (wrap) для завертання довгих ліній. Ви знайдете ще декілька опцій ps у сторінці посібника до цієї програми. Kill Зрідка, програми поводяться не так як належить і вам необхідно якимось чином вплинути на них. Програмою для таких завдань являється kill(1), яка може впливати на перебіг процесів у декілька способів. Найбільш очевидне завдання kill — це знищити процес — буває необхідним коли останній зациклено і споживає всі системні ресурси. Для того щоб знищити процес, вам необхідно знати PID, тобто ідентифікаційний номер процесу. Використайте команду ps, яку ми пройшли у попередньому розділі, для цього. Так, наприклад, щоб вбити процес під номером 4747, виконайте наступне: $ kill 4747Звичайно, ви повинні бути володарем цього процесу для того щоб його знищити. Це одна з рис безпеки системи, тож користувачі не можуть переривати процеси які їм не належать. root-користувач, як і очікується, може перервати будь-який процес. Одним з різновидів kill є програма killall(1). Остання зупинить всі процеси з певною, наданою вами, назвою. Наприклад, якщо би ви хотіли вбити всі процеси під назвою mozilla-bin, командою було б: $ killall mozilla-binЛюбі, запущені вами програми mozilla-bin, будуть припинені. Ця сама команда, виконана root-користувачем, вб'є всі процеси mozilla-bin усіх користувачів. Останнє приводить до цікавого способу викинути тимчасово всіх користувачів з системи, включаючи самого root-користувача, командою: # killall bashІноді буває деякі програми відмовляються завершити свою роботу при використанні звичайної команди kill. В такому разі, необхідно використати агресивнішу форму kill: $ kill -9 4747Обидві kill і killall візьмуть як аргумент номер, що відповідає сигналу який можна послати процесові. Звичайна kill посилає більш цивілізований сигнал SIGTERM, що вказує процесові завершити роботу, очистити пам'ять і вийти, тоді як останньому прикладі -9 означатиме потужніший SIGKILL, що нагально перериває процес. Загалом, SIGKILL використовується лише в крайніх випадках, оскільки він може призвести до псування даних. Ви можете отримати список всіх можливих сигналів за допомогою прапорця -l (англійська "л") (list): $ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWRКрім номерів сигналів, також можна використовувати їхні назви без префіксу "SIG", наприклад: $ killall -KILL xeditЩе одним застосуванням kill буде рестарт процесів. Якщо ви пошлете сигнал SIGHUP програмі, вона рестартує, перечитавши власний конфігураційний файл, якщо такий є. Це особливо корисно для того щоб заставити системним процесам перечитати файли конфігурації після їхнього редагування. ДОДАТОК 3. Приклад програми пересилки повідомлень між паралельними процесами
#include "mpi.h" main (argc, argv) int argc; char **argv; { char message[20]; int myrank; MPI_Status status; MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &myrank); if (myrank==0) /* code for process zero */ { strcpy (message, "Hello, MPI"); MPI_Send(message, strlen(message), MPI_CHAR, 1, 99, MPI_COMM_WORLD); } else /* code for process one */ { MPI_Recv (message, 20, MPI_CHAR, 0, 99, MPI_COMM_WORLD, &status); printf ("received :%s:\n", message); } MPI_Finalize(); } ДОДАТОК 4. Програма, що виводить кількість паралельних процесів та їх номери
#include <stdio.h> #include <mpi.h>
int main(int argc, char** argv){ int allproc, procid, namelen; char processor_name[MPI_MAX_PROCESSOR_NAME]; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &allproc); MPI_Comm_rank(MPI_COMM_WORLD, &procid); MPI_Get_processor_name(processor_name,&namelen); if (procid == 0) { printf("All processes count is: %d \r\n", allproc); } printf("Process %d on %s\n", procid, processor_name); MPI_Finalize(); return 0; }
ДОДАТОК 5. Приклад розпаралелення ітераційного процесу
#include "mpi.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h>
#define BUFLEN 512
int main(argc,argv) int argc; char *argv[]; { int i, myid, numprocs, next, rc, namelen; unsigned long j1, j2, sum=0; char buffer[BUFLEN], processor_name[MPI_MAX_PROCESSOR_NAME]; double startwtime = 0.0, endwtime; MPI_Status status; int iter=10, iter2=15000, iter3=25000, piter; char studName[20]="";
MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&numprocs); MPI_Comm_rank(MPI_COMM_WORLD,&myid); MPI_Get_processor_name(processor_name,&namelen);
if (myid == 0) { printf("-=- Enter your surname: "); scanf("%20s", studName); printf("-=- Enter number of iterations: "); scanf("%u", &iter); printf("-=- Amount of Parallel Processes: %d\n-=- Total Iterations: %ux%dx%d\n", numprocs, iter, iter2, iter3); for (i=0;i<numprocs;i++) MPI_Send(&iter, 1, MPI_INT, i, 0, MPI_COMM_WORLD); }
MPI_Recv(&iter, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); MPI_Barrier(MPI_COMM_WORLD); /* synchronization */
if (myid == 0) startwtime = MPI_Wtime(); /* time stamp of start*/
piter=iter/numprocs; /* partial iterations */
if (myid == 0) if (iter%numprocs > 0) piter=piter+(iter%numprocs); for (i=1;i<=piter;i++) { for (j1=1;j1<=iter2;j1++) { for (j2=1;j2<=iter3;j2++) sum = sum + 1; } printf("Process %d on processor %s Iteration - %d \n",myid,processor_name,i); } MPI_Barrier(MPI_COMM_WORLD);
if (myid == 0) endwtime = MPI_Wtime();
MPI_Finalize();
if (myid == 0) printf("-=- Wall Clock Time: %f\n", endwtime-startwtime); }
|