KNOW INTUIT, Лекция, Организация на вход-изход в UNIX
Изпълнение на програмата с персонализирана обработка на сигнала SIGINT
Помислете сега за друга програма - 13–14-3.c :
Тази програма се различава от програмата в „Изпълнение на програма, която игнорира сигнала SIGINT“ по това, че въвежда обработка на сигнала SIGINT от дефинирана от потребителя функция. Въведете, компилирайте и стартирайте тази програма, тествайте нейната реакция при натискане на CTRL > и и при натискане на CTRL > И .
Модификация на предишната програма за персонализирана обработка на сигнали SIGINT и SIGQUIT
Променете програмата от предишния раздел, така че да отпечатва и съобщение за CTRL > И . Използвайте същата функция за обработка на сигнали SIGINT и SIGQUIT. Компилирайте и го стартирайте, проверете дали работи правилно. Също така ще трябва да премахнете програмата от друг терминал с командата kill.
Възстановяване на предишния отговор на сигнала
Досега в примерите игнорирахме стойността, върната от системното извикване signal(). Това, което всъщност прави това системно извикване, е да върне указател към предишния манипулатор на сигнала, което ви позволява да възстановите отменения отговор на сигнала. Разгледайте примерната програма 13-14-4.c, която връща първоначалния отговор на сигнала SIGINT след 5 потребителски обработки на сигнала.
Въведете, компилирайте програмата и я стартирайте за изпълнение.
Сигнали SIGUSR1 и SIGUSR2. Използване на сигнали за синхронизиране на процеси
В операционната система UNIX има два сигнала, които могат да бъдат генерирани само от системното извикване kill() или командата kill, това са сигналите SIGUSR1 и SIGUSR2. Те обикновено се използват за предаване на информация занастъпило събитие от един потребителски процес към друг като сигнализиращо средство за комуникация.
В материалите на семинар 5 (раздел „Писане, компилиране и изпълнение на програма за организиране на двупосочна комуникация между свързани процеси чрез тръба“), когато се разглеждаше комуникацията на свързани процеси чрез тръба, беше казано, че тръбата е еднопосочен комуникационен канал и че за да се организира комуникация през една тръба в две посоки, е необходимо да се използват механизмите за взаимна синхронизация на процесите. Установете двупосочна серийна комуникация между родителския процес и дъщерния процес чрез канал, използвайки сигналите SIGUSR1 и SIGUSR2 за синхронизация, като модифицирате програмата от раздела. „Стартиране на програма за организиране на еднопосочна комуникация между свързани процеси чрез канал“ на семинар 5.
Разширено предизвикателство: Разменете битово цяло число между два процеса, като използвате само сигналите SIGUSR1 и SIGUSR2.
При внедряване на нишки за изпълнение в операционната система Linux (вижте семинари 6-7, започвайки с раздела „Концепцията за нишка за изпълнение (нишка) в UNIX. Идентификатор на нишка. Функция pthread_self (“), сигналите SIGUSR1 и SIGUSR2 се използват за организиране на синхронизация между процесите, представляващи нишки за изпълнение, и процеса на координатора за целите на услугата. Следователно потребителските програми, използващи нишки за изпълнение,не могат да използватсигналите SIGUSR1 и SIGUSR2.
Прекратяване на дъщерния процес. Системното повикване waitp > В семинари 3-4 (раздел „Прекратяване на процес. Функцията exit()“), когато се изучаваше прекратяването на процес, беше казано, че ако дъщерният процес излезе преди родителския процес, и родителският процесне посочи изрично, че не се интересува от получаване на информация за изходния статус на дъщерния процес, тогава прекратеният процес не изчезва напълно от системата, но остава в състояниезавършено изпълнение(зомби процес) или докато родителският процес приключи, или до момента, в който родителят благоволи да получи тази информация.
Родителският процес може да използва системното извикване waitpid() или неговата опростена форма wait(), за да получи тази информация. Системното извикване на waitpid() позволява на родителски процес синхронно да получи статуса на прекратен дъщерен процес или чрез блокиране на родителския процес, докато дъщерният процес приключи, или без блокиране, като го извиква периодично с опцията WNOHANG. Тези данни заемат 16 бита и могат да бъдат декодирани, както следва в рамките на нашия курс:
- Ако процесът завърши с изрично или неявно извикване на функцията exit(), тогава данните изглеждат така (най-значимият бит е отляво):
Всеки дъщерен процес изпраща специален сигнал SIGCHLD към родителския си процес, когато се прекрати, към който всички процеси имат зададен по подразбиране отговор "игнориране на сигнал". Наличието на такъв сигнал, заедно със системното извикване waitpid(), позволява да се организира асинхронно събиране на информация за статуса на прекратените дъщерни процеси от родителския процес.
Системните извиквания wait() и waitpid()
Прототипи на системни повиквания
Описание на системните повиквания
Това описание не е пълно описание на системните повиквания, но е адаптирано, за да отговаря на нашия курс. Вижте ръководството за UNIX за пълно описание.
Системното извикване на waitpid() блокира изпълнението на текущия процес, докато някой от дъщерните процеси излезе.процесът, посочен от стойността на параметъра pid, или текущият процес няма да получи сигнал, който е зададен на отговора по подразбиране „прекратяване на процеса“ или отговора за обработка на дефинирана от потребителя функция. Ако дъщерният процес, указан от параметъра pid, е в завършено състояние по време на системното извикване, тогава системното извикване се връща незабавно, без да блокира текущия процес.
Параметърът pid указва дъщерния процес, който родителският процес чака да приключи, както следва:
- Ако pid > 0 изчакване pid на процеса да приключи.
- Ако p >, изчакайте прекратяването на всеки дъщерен процес в групата, към която принадлежи родителският процес.
- Ако p >, изчакайте всеки дъщерен процес да приключи.
- Ако pid не е -1, изчакайте всеки дъщерен процес от групата, чийто ID е равен на абсолютната стойност на параметъра pid, да приключи.
Параметърът опции в нашия курс може да приема две стойности: 0 и WNOHANG. Стойността WNOHANG изисква повикването да се върне незабавно, без да блокира текущия процес в никакъв случай.
Когато се установи, че даден процес е прекратен, системното извикване връща идентификатора на процеса. Ако извикването е направено с набор от опции WNOHANG и дъщерният процес, определен от pid, съществува, но все още не е прекратен, системното извикване ще върне стойността 0. Във всички останали случаи връща отрицателна стойност. Връщането от повикването, свързано с появата на обработен от потребителя сигнал, може след това да бъде идентифицирано чрез стойността на системната променлива errno == EINTR и повикването може да бъде направено отново.
Системното извикване на wait е синоним на системното извикване на waitpid със стойностиопции p >, опции = 0 .
Използвайки системното извикване signal(), можем изрично да настроим този сигнал да бъде игнориран ( SIG_IGN ), като по този начин информираме системата, че не се интересуваме как завършват създадените процеси. В този случай няма да се появят зомби процеси, но използването на системните извиквания на wait() и waitpid() ще бъде деактивирано.
Стартиране на програмата за илюстриране на обработката на сигнала SIGCHLD
За да консолидирате материала, разгледайте примерната програма 13-14-5.c с асинхронно получаване на информация за изходния статус на генерирания процес.
В тази програма родителят ражда два процеса. Единият излиза с код 200, а вторият зацикля. Преди процесите на хвърляне на хайвера, родителят настройва манипулатор на прекъсване за сигнала SIGCHLD и след хвърлянето на хайвера той преминава в безкраен цикъл. В манипулатора на прекъсвания, waitpid() се извиква при всеки създаден процес. Тъй като стигаме до манипулатора, когато някой от процесите е прекратен, системното извикване не е блокирано и можем да получим информация за идентификатора на прекратения процес и причината за неговото прекратяване. Компилирайте програмата и я стартирайте за изпълнение. Прекратете втория създаден процес с командата kill с някакъв номер на сигнала. Родителският процес също ще трябва да бъде прекратен с командата kill.