Linux операциондық жүйесінде kill функциясын оқып үйрену және оны Си тілінде программалау



Кіріспе ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 4
1 Сигналдар ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...5
1.1 Сигналдарды өңдеу ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... .7
1.2 Үрдістер тобы ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 14
1.3 Сигналдарды үрдістермен жіберу ... ... ... ... ... ... ... ... ... ... ... ... 14
2 Linux операциялық жүйесінің функциялары ... ... ... ... ... ... ... ... ... ... 16
2.1 wait() функциясы ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ..16
2.2 fork() функциясы ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 17
2.3 ехес() функциясы ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...18
2.4 pipe() функциясы ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...19
3 Kill функциясы ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 21
3.1 Сигналды беру үрдісі: kill ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... .21
3.2 Туынды үрдістердің “өлімі” ... ... ... ... ... ... ... ... ... ... ... ... ... ... .23
3.3 Үрдістің тоқтатылуы мен жаңаруы ... ... ... ... ... ... ... ... ... ... ... .25
Қорытынды ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... .29
Қолданылған әдебиеттер ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 30
Қосымша
kill() жүйелік шақыруды қолдана отырып, үрдіс басқа үрдіске сигнал жібере алады. Жүйелік шақыру kill() үшін оның аты оның қызметіне мінезделмейді, себебі оның жібере алатын көптеген сигпалдары үрдісті аяқтамайды (“өлтірмейді”). Шақыру өзінің тарихи себептеріне баіланысты алған: UNIX құрылған кезде сигналдарды қолданудың негізі үрдісті аяқтау болып табылады.
kill командасын әдетте үрдістін орындалуын тоқтату үшін қолданады. Бұл команда үрдіске кез келген сигналды жібере алады, ал егер көрсетілмесе ол TERM программаны аяқтау сигналын жібереді. kill командасын қарапайым пайдаланушылар да (өздерінің жеке үрдістері үшін), привилегиялық пайдаланушылар да (кез келген үрдіс үшін) қолдана алады.
1. Стивенс У. UNIX, взаимодействие процессов. – М.: Питер, 2002
2. Гордеев А.В., Молчанов А.Ю. Системное программное обеспечение. - СПб.: Питер, 2001
3. Дейтл Г. Введение в операционные системы. В 2-х томах. Пер.с англ. – М.: Мир, 1987
4. Концептуальное моделирование информационных систем. /Под.ред. В.В.Фильчакова. – СПб: СПВУРЭ ПВО, 1998
5. Клочко В.И. Теория вычислительных процессов и структур. Учебное пособие. – Краснодар: Издательство КубГТУ, 1999
6. Кейт Хэвиленд, Дайана Грэй и др. Системное программирование UNIX. – М.: Москва, 2000
7. Операционные системы – от РС до РS/2/ Ж.Фодор, Д.Бонифас, Ж.Танги. Пер. с франц. – М.: Мир, 1992
8. Олифер В.Г., Олифер Н.А. Сетевые ОС.- СПб.: 2002
9. Хелен Кастер. Основы Windows NT и NTFS. Пер.с англ. – М.: Отдел Русская редакция “ТОО-Channel Traiding ltd”, 1996
10. Эви Немет, Гарт Снайдер и др. UNIX. Руководство системного администратора. – Киев, 2000
11. Корнеев В.В. Параллельные вычислительные системы. Москва, 1999

ҚАЗАҚСТАН РЕСПУБЛИКАСЫНЫҢ
БIЛIМ ЖӘНЕ ҒЫЛЫМ МИНИСТРЛIГI

Қаныш Сәтбаев атындағы
ҚАЗАҚ ҰЛТТЫҚ ТЕХНИКАЛЫҚ УНИВЕРСИТЕТI

Ақпараттық технoлогиялар институты

Есептеу техникасы кафедрасы

КУРСТЫҚ ЖҰМЫСҚА ТҮСIНIК

Тақырыбы: Linux операциондық жүйесінде kill функциясын оқып үйрену және оны
Си тілінде программалау

Жетекшiсi: аға оқытушы

Сейілова Н.А.. аты-жөнi

Бақылаушы: аға оқытушы

Сейілова Н.А. аты-жөнi

“__” __________ 2005 ж

Орындаған: Мутанова С.А.

Мамандығы: 050704

Тобы: ВПбП-04-8Қ

Алматы 2005

Курстық жұмысты орындауға тапсырма

Студент: Мутанова С.А.

Тақырыбы: Linux операциондық жүйесінде kill функциясын оқып үйрену
және оны Си тілінде программалау

Аяқталған жұмысты тапсыру уақыты

“__“ _________ 2005.

Жұмыс барысында қолданылатын бастапқы мәлiметтер

(мазмұны, жұмысты сипаттайтын негiзгi бөлiм, қорытынды)

Сызба материалдар саны:

Жұмыс жетекшiсi: Сейілова Н.А.

Тапсырманы орындауға қабылдап алған студент Мутанова С.А.

“__“ _________ 2005.

Мазмұны
Кіріспе ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... .
... ... ... ... ... ... ... ... ... ... ... .4
1
Сигналдар ... ... ... ... ... ... .. ... ... ... ... ... ... ... ... ... ... ..
... ... ... ... ... ... ... ... 5
1.1 Сигналдарды
өңдеу ... ... ... ... ... ... ... .. ... ... ... ... ... ... ... ... ... ... ..
..7
1.2 Үрдістер
тобы ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ..
... ... 14
1.3 Сигналдарды үрдістермен
жіберу ... ... ... ... ... ... ... . ... ... ... ... ...14
2 Linux операциялық жүйесінің
функциялары ... ... ... ... ... ... ... ... ... ... 16
2.1 wait()
функциясы ... ... ... ... ... ... .. ... ... ... ... ... ... ... ... ... ... ..
... ...16
2.2 fork()
функциясы ... ... ... ... ... ... .. ... ... ... ... ... ... ... ... ... ... ..
... ... .17
2.3 ехес()
функциясы ... ... ... ... ... ... .. ... ... ... ... ... ... ... ... ... ... ..
... ... 18
2.4 pipe()
функциясы ... ... ... ... ... ... .. ... ... ... ... ... ... ... ... ... ... ..
... ... 19
3 Kill
функциясы ... ... ... ... ... ... .. ... ... ... ... ... ... ... ... ... ... ..
... ... ... ... ... .21
3.1 Сигналды беру үрдісі:
kill ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ..21
3.2 Туынды үрдістердің
“өлімі” ... ... ... ... ... ... ... ... ... ... ... ... ... ... .23
3.3 Үрдістің тоқтатылуы мен
жаңаруы ... ... ... ... ... ... ... ... ... ... ... .25
Қорытынды
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ..
... ... ... ... ... .29
Қолданылған
әдебиеттер ... ... ... ... ... ... . ... ... ... ... ... ... ... ... ... ... ..
... ... ..30
Қосымша

Кіріспе
kill() жүйелік шақыруды қолдана отырып, үрдіс басқа үрдіске сигнал
жібере алады. Жүйелік шақыру kill() үшін оның аты оның қызметіне
мінезделмейді, себебі оның жібере алатын көптеген сигпалдары үрдісті
аяқтамайды (“өлтірмейді”). Шақыру өзінің тарихи себептеріне баіланысты
алған: UNIX құрылған кезде сигналдарды қолданудың негізі үрдісті аяқтау
болып табылады.
kill командасын әдетте үрдістін орындалуын тоқтату үшін қолданады. Бұл
команда үрдіске кез келген сигналды жібере алады, ал егер көрсетілмесе ол
TERM программаны аяқтау сигналын жібереді. kill командасын қарапайым
пайдаланушылар да (өздерінің жеке үрдістері үшін), привилегиялық
пайдаланушылар да (кез келген үрдіс үшін) қолдана алады.

1 Сигналдар

Сигналдар үрдістерге асинхронды жағдайлардың пайда болған туралы
жеткізеді. Бір-біріне сигналдарды жіберу үрдістермен жүргізіледі, ол kill
функциясы көмегімен немесе ядромен жүреді. Unix жүйесіндегі 5-ші версия-
сында 19 түрлі символдар бар, оларды келесідей классифицировать етуге
болады:
• Үрдістің орындалуын аяқтау кезінде жіберілетін сигналдар, бұл
дегеніміз, үрдіс exit немесе signal функциялары death of child
(ұрпақтың өлуі) параметрімен бірге орындалады;
• Үрдістің ерекше жағдайды шақыруды пайда болған жағдайда жіберілетін
сигналдар, оларға үрдістің виртуалды мекен аймағының тыс орналасқан
мекенге жолығу немесе жады аймағында оқу үшін ғана ашылатын (мысалы,
программаның мәтіні) жазуды орындау, немесе привилегиялы командаларды
орындауды, сонымен қатар әртүрлі аппараттық қателердің орындалуын
көру;
• Түзетілмейтін қателердің пайда болғандағы жүйелік функция-лардың
орындалып жатқанда жіберілетін сигналдар, оларға шығатын мекендік
аймақтың босауынан кейін, exec функциясының орындалу ке-зіндегі
жүйелік қорды жою жатады;
• Жүйелік функцияның мүлдем күтпеген қателердің орындалу уақытында пайда
болғанына қызмет ететін себептері бола алатын сиг-налдар, оларға жоқ
жүйелік функцияларға қатынасу (үрдіс жүйелік функция, ешбір бар
функцияның біреуінде жоқ нөміріне беру), ешбір оқылу үрдісімен
байланыссыз каналдарға жазу, сонымен қатар Iseek жүйелік функциясының
“reference” параметрінде болмайтын мәнді қолдану жатады. Қайткенде де,
бұндай жағдайда логикалық тұрғыдан қарағанда сигналды жібергеннің
орнына қатенің кодын қайтарған жөн болар еді, бірақ практикалық
тұрғыдан қарағанда үрдістерді осындай қателер болған жағдайда
авариялық түрде аяқтауда сигналдардың (*) қолданғаны дұрысырақ болады;
• Есептеу режимінде орындалатын, үрдіске жіберілетін сигнал-дар, мысалы,
белгілі бір уақыт периоды өткенде жіберілетін тривога сигналы
(alarm), немесе kill функциясын қолданатын үрдістер өзара ауыстыратын
ерікті сигналдар;
• Терминалдар әрекеттесуімен байланысатын сигналдар, мысалы, терминалдық
тұрып қалуымен (кез келген себепке байланысты терминалдың сызығында
толушы-сигнал аяқталған кезде) немесе терминалдың пернетақтасында
“break” және “delete” түймешіктерінің басылуымен;
• Олардың көмегімен үрдістің орындалу із салуы болатын сиг-налдар. Осы
бөлімде әр топтардағы сигналдардың қолдану шарттары қарастырылады;
Ядро қалай сигналдарды үрдіске жіберетіні, қалай үрдіс сигналдарды
өңдейді және оларды реакциясын басқаратындығы сияқты концепция сигналдарды
бірнеше аспектілері болады. Үрдістерге сигнал жібере отырып, ядро сигналдар
типіне сәйкес келетін үрдістер кестесіне санаулы разрядты сигналдар
кеңістігіне жазуды орналастырады. Егер үрдіс үзуді орындайтын
артықшылығымен тоқтату күйінде болса, ядро оның орындалуын жаңартады. Бұдан
сигналдың жіберу рөлі (үрдіс немесе ядро) сызылады. Үрдіс түрлі типті
сигналдарды еске сақтай алады, бірақ қабылдайтын әр типтің сигналы-ның
көлемін еске сақтай аламыз. Мысалы, егер үрдіс “тоқтап қалу” немесе жүйеден
үрдістің жойылғаны туралы сигнал алса, ол үрдістер кестесінің сигналдар
кеңістігіне санаулы сәйкес разрядты орнатады, бірақ ол сигналдың әр типінің
қанша данасын алғанын айта алмайды.
Ядро, үрдіс ядро режимінен есептеуші режиміне өтейін деген кезде,
сигналдың алуын тексереді, сонымен қатар ол тоқтау күйінен өтеді немесе
күйден жеткілікті төмен жоспарлау артықшылығымен шығады. Ядро сигнал-ды
үрдіс ядро режимінен есептеуші режимне қайтқан жағдайда ғана өңдейді.
Сондықтан сигнал ядро режимінде орындалатын үрдістің іс-әрекетіне жыл-дам
әсер етпейді. Егер үрдіс есептеу режимінде орындалса, ядро ол уақытта
үрдісіне сигналды жіберуге әсер еткен үзрді өңдесе, ядро үзуден шығуда
сигналды танып және өңдейді. Сол себептен, үрдіс есептеу режимінде басқа
сигналдар өңделмей қалғанда орындалмайды.
1-суретте ұсынылған алгоритм көмегімен ядро үрдістің сигналды
қабылдағаны немесе қабылдамағанын анықтайды. Егер үрдіс signal функция-сын
қолданатын болса, онда біз оның басқа сигналдарды жақтырмайтынды-ғын
көреміз. Issig алгоритмінде ядро үрдіс мән бергісі келмейтін сигналдар-дың
идентификациясын өлтіреді және басқа қалған сигналдарға үрдістің зейінін
салады.

Issig алгоритмі *сигналды қабылдауды тексеру*
кіретін ақпарат: жоқ
шығатын ақпарат: егер үрдіс оған қызығушылығы бар сигналды
қабылдаса ақиқат, кері
жағдайда жалған
{
Орындай бер (сигналды қабылдау туралы индикациясы бар үрдістер
кесте жазуындағы өрісте нөлдік мәнді сақтау)
{
Үрдіске жіберілген сигналдың нөмірін табу;
егер (сигнал типі ұрпақтың өлуі)
{
Егер (берілген типтің сигналы жақтыртпаса) өмір сүруі
тоқтатылған ұрпаққа сәйкес үрдістер кестесіндегі
жазуды босатса;
кері жағдайда егер (берілген типтегі сигналдар
қабылданса)
(ақиқатты) қайтару;
}
кері жағдайда егер (сигнал жақтытпаса)
(ақиқатты) қайтару;
сигналды қабылдау индикациясын сақтайтын үрдістер кестесі
сәйкес үрдісте орнатылған сигналдық разрядты тастау (өшіру);
}
(жалғанды) қайтару;
}

1-сурет. Сигналдарды тану алгоритмі.

1.1 Сигналдарды өңдеу
Ядро үрдістің контекстінде оны алатын сигналдарды өңдейді. Сол
себептен сигнал өңдеу үшін үрдісті іске қосу қажет. Сигнал өңдеудің 3 әдісі
бар: үрдіс сигналды қабылдағаннан кейін аяқталады және сигналға мән
бермейді немесе оны қабылдағаннан кейін ерекше функция орындайды. Ядро
режимінде қолданылатын үрдіс жағынан келісімді реакция exit функциясын
шақыру болып табылады, дегнімен де signal функциясының көмегімен үрдіс
немесе басқа сигналдарды үндемелі қабылдайтын басқа арнайы іс-әрекеттер-ді
бағыттай алады.
signal функциясының жүйелік шақыру синтаксисі:
oldfunction = signal(signum, function);
мұнда, signum – сигнал нөмірі, ол қабылданған кезде пайдаланушы функция-сы
іске қосумен байланысты іс-әрекет орындалады, function – функция меке-ні,
oldfunction – функцияның мәнін қайтару. Үрдіс функция мекенінің орнына
шақырылатын signal процедурасына 1 және 0 сандарын бере алады: егер
function=1 болса, үрдіс signum нөмірімен келесі түсетін сигналдарды жақтыр-
майды (жақтырмайтын сигналдарға байланысты ерекше жағдай ол ұрпақ-тардың
өлуі), егер 0-ге тең болса (келісулі мән бойынша), үрдіс сигналды ядро
режимінде қабылдауымен аяқталады. Сигналды өңдеу үшін үрдіс аума-ғында
массив кеңістігі қолдау көрсетеді, әр арнайы жүйедегі сигналға бір
кеңістіктен нөмірі көрсетілген сәйкес сигналдың кеңістігінде ядро пайдала-
нушы функция үрдістің сигнал қабылдағышынан шақырылатын шешімін сақтайды.
Бір типті сигналдың өңдеу әдісі, басқа типті сигналдың өңдеуіне әсер
етпейді.
psig агоритмі *оның бар болғанын тексергеннен кейін сигналды
өңдеу*

кіретін ақпарат: жоқ
шығатын ақпарат: жоқ
{
үрдістер кестесінің жазуынан сигнал нөмірін таңдау;
сигнал нөмірімен өрісті тазарту;
егер (signal функциясын алдын ала шақырды, соның көмегімен берілген
типтің сигналын жақтыртпауға нұсқау берілді)
басқаруды қайтару;
егер (сигналды алғаннан кейін орындау керек функцияны
пайдаланушы көрсетеді)
{
үрдіс кеңістігінен сигналды өңдеу функциясының пайдаланушы
виртуалды мекенін таңдау;
* келесі оператор керек емес жанама әсер болады *
сигналды өңдеу функциясының мекені болатын үрдістегі
кеңістіктегі өрісті тазарту;
пайдаланушы контекстіне өзгерту енгізу:
сигналды өңдеу функциясына еліктеуді үндейтін жазуды
есептеу стегінде жалған құру;
жүйелік контекстіне өзгерту енгізу:
команда счетчигінің өрісінде сигналды өңдеу функциясының
мекенін жазу, ол сақталған контекстік есебіне жатады;
басқаруды қайтару;
}
егер (сигнал жадыда үрдістің пішінін дампирлеуді талап етсе)
{
ағымдағы каталогта “corn” атымен жайл құру;
“corn” файылына пайдаланушы контекстінің мазмұнын жазу;
}
exit алгоритмін тез арада жүктеу;
}

2-сурет. Сигналды өңдеу алгоритмі.

Сигналды өңдей тұра (2-сурет), ядро сигналдың типін анықтайды және
үрдістер кестесінің жазуының разрядынтазартады (өшіреді), ол берілген
сигнал типі бойынша сәйкес келеді және сигналды үрдіспен қабылдау кезінде
орнатады. Егер сигналды өңдейтін функциясы келісілген мәнді өзіне алса,
ядро басқа жағдайда үрдісті аяқтау алдында жадыдағы үрдіс күйіне сыртқы
тасымалдаушыға (дампирлайды) тастайды. Дампирлау программистер үшін тиімді,
себебі ол жадыдағы сигналдың түсуін анықтайды және осыған байланысты
программаның тыс қалуын енгізеді. Ядро үрдістің орындалуын-дағы кейбір
қателіктерді жіберетін сигналдардың түскенде, жадының жағдайын дампирлайды,
оларға мысал ретінде тиым салынған командалар-дың орындалуы немесе үрдістің
виртуалды мекен кеңістігінен тыс орналас-қан мекенге жолығу. Егер сигнал
программалық қатемен қатнаспаса, ядро жады жағдайын димпирлайды. Мысалы,
терминалдағы “delete” немесе “break” түймешігін басумен шақырған үзу,
өзінің пайдаланушы үрдісті уақытынан бұрын аяқтағысы келетін сигналды
жіберу қорытындысы болады, бұл уақытта тоқтап қалу сигналы регистрациялы
терминалмен бірге бүлінуі туралы куәлік бола алады. Бұл сигналдар үрдістің
ағынының қатесі-мен байанысты болмайды. Шығу туралы сигнал (quit),
дегенімен де үрдістің орындалуынан тыс болатынына қарамастан жады жағдайын
тастауды шақырады. Бұл сигнал әдетте ctrll түймешігін басумен бірге
шақырылады, егер үрдіс бір камандалардың шексіз циклмен орындалатынына
түссе, қажет болатын прогаммистке үрдісті іске қосқан уақытынан кейін кез
келген сәтте жады жағдайынан дамп алуға мүмкіндік береді.
Егер үрдіс алдында мән бермейміз деп келіскен сигналды алса, үрдіс ол
сигналды болмады деп орындалуын жалғастырамыз. Ядро сәйкес кеңістіктің
берілген типті сигналды жақтырмауды керек екенді анықтайтын мәнін
тастамағандықтан, сигнал қайтадан түскен кезде үрдіс оған тағы да мән
бермейді. Егер үрдіске әсер ету керек болатын сигналды алатын болса,
есептеуші режимінде үрдісті қайтарғаннан кейін алдын ала шартталған іс-
әрекен орындалады, дегенімен де үрдісті есептеуші режимінде ауыстыру
алдында, ядро келесі қадамдарды қабылдау керек:
1. ядро сақталған егистрлік есепке жолығып, стек төбесінің көрсеткішін
және командаларды септеу мәнін таңдайды, пайдаланушы үрдіске
қайтарады.
2. сигналды өңдеу функциясы кеңістігіне алдынғы мәнді үрдіс кеңістігіне
тастайды және келісім бойынша оған мән береді.
3. керектігіне сай қосымша жады бөлінетін есептеу стегіне жаңа жазу
шығарады, алдында таңдалған сақтаулы есептеу контекстік регис-трлігіне
стек төбесінің көрсеткішін және команда счетчигінің мәнін жазады.
Есептеуіш стегі үрдіс пайдаланушы функциясын (сигналды өңдеу), оның
жүйелік функциясына шақырған немесе ядро оның орын-далуын үзген
(сигналды танымай тұрып) жеріндегі нүктеден қараған сияқты көрінеді.
4. сақталған регистрлік есеп контекстке өзгерту енгізу: сигналды өңдеу
функциясын мекенін тең счетчик командасының мәнін орнатады, ол стек
төбесінің көрсеткішінің мәнің есептеу стегінің түбіне тең.
Сол сияқты, қайтуы бойынша ядро режимінен есептеу режиміне үрдіс
сигналды өңдеу функциясын орындалуына кіріседі; оны аяқтаған соң басқару
пайдаланушы программасындағы жүйелік функцияға жолыққан немесе үзу болған
жерге беріледі, сонымен жүйелік функция немесе үзуден шығуды еліктетеді.
Мысал ретінде 3-суретті алуға болады, ол үзу туралы сигналды (SIGINT)
қабылдайды және өзі де оларды жібереді (kill функциясы орындалу
қорытындысында). 4-суретте VAX 11780 операциондық жүйедегі жүктеуші
дисассемблированияның қорытындысын алғандағы программалық кодтың бөлшектері
көрсетілген. Үрдістің орындалуындағы kill библиотекалық процедурасында
жолыққан ее (он алтылық) мекені болады; бұл процедура kill жүйелік
функциясын шақырғаннан бұрын 10а мекені бойынша chmk командасын орындайды
(үдісті ядро режиміне ауыстыру). 10с – жүйелік функциядан мекенді қайтару.
Жүйелік функция орындалу кезінде ядро үрдіс-ке үзу туралы сигнал жібереді.
Ядро бұл сигналға үрдіс есептеуіш режиміне қайтайын деп жатқанда мән
береді, 10с мекенді қайтаруы сақталған регистр-лік контекстен таңдап және
есептеу стегіне орналастырады. Онымен қоса 104 сигналды өңдеу функция
мекеніне, ядро сақталған регистрлік есептеу кон-текстіне орналстырады.
Қаралған сигналдарды өңдеу алгоритмінде бірнеше сәйкссіздіктер бар.
Олардың ең негізгі және бірінші үрдіс кеңістігіндегі есептеу режиміне
қайтару үрдісінен бұрын тазалаумен байланысты, оның өзінде сигналды өңдеу
функциясын пайдланушы мекені бар. Егер үрдіске тағы да сигналды өңдеу керек
болса, ол тағы да signal жүйесін функциясына көмекке келуге тура келеді.
Бұндайда болу керек емес жағдайлары болады:мысалы, бәсекеге жақсы жағдай
тууы мүмкін, егер екінші рет үрдіс жүйелік функцияны іске қосуға мүміндік
алғанша дейін сигнал түссе. Үрдіс есептеу режимінде орын-далатындықтан,
ядроға контексті ауыстыруға тура керек болады, сонымен үрдістің сигналды
өңдеу функция өріске мәндерді тастау алдында сигналды алуға мүмкіндікті
жоғарылатуы үшін.
#include signal.h
main()
{
extern catcher();
signal(SIGINT,catcher);
kill(0,SIGINT);
}

catcher()
{
}

3-сурет. Сигналды қабылдау программасының мәтіні

**** VAX DISASSEMBLER ****

_main()
e4:
e6: pushab Ox18(pc)
ec: pushl $Ox2
# келесі жол signal функциясын шақырады
ee: calls $Ox2,Ox23(pc)
f5: pushl $Ox2
f7: clrl -(sp)
# келесі жол библиотекалық kill процедурасын шақырады

f9: calls $Ox2,Ox8(pc)
100: ret
101: halt
102: halt
103: halt
_catcher()
104:
106: ret
107: halt
_kill()
108:
# келесі жолда операциялық жүйенің ішкі үзуі шақырылады

10a: chmk $Ox25
10c: bgequ Ox6 Ox114
10e: jmp Ox14(pc)
114: clrl r0
116: ret

4-сурет. Сигналды қабылдау программасының дисассемблерлік қорытындысы.

Бұл жағдайды 5 – суретте көрсетілген программа мысалында қарасты-руға
болады. Үрдіс signal жүйелік функциясына үзіліс туралы сигналды қабылдауға
және оны қабылдағаннан кейін sigcatcher функциясын орындауға нұсқау беру
үшін жүгінеді. Одан кейін ол жаңа үрдісті туғызады, ол ата-ана үрдісінің
іске қосылу приоритетін оның ұрпағының приоритетінен төмендетуге мүмкіндік
беретін nice жүйелік функциясын іске қосады және шексіз циклге кіреді.
Пайда болған үрдіс өзінің орындалуын ата-аналық үрдіске nice жүйелік
функциясын орындауға уақыт беру үшін және өзінің приоритетін төмендету үшін
5 секундқа кідіреді. Бұдан кейін пайда болған үрдіс әрбір итерациясында ол
ата-аналық үрдіске үзіліс туралы сигнал беретін циклге енеді (kill
функциясына жүгіну арқылы). Егер қате болса, мысалы, ата-аналық үрдіс жоққа
айналғанда, kill аяқталады, онда пайда болған үрдіс те тоқтайды. Бұның бар
мақсаты болып, ата-аналық әрбәр үзіліс туралы сигнал алған сайын өңдеу
функциясын іске қосу жатады. Сигналды өңдеу функциясы хабарлама шығарады
және үзіліс туралы сигнал пайда болғанда signal функциясына қайтадан
жүгінеді, ал ата-аналық үрдіс циклдік команда жинауын жалғастыра береді.
Алайда, оқиғаның болу кезегі келесідегідей болуы мүмкін:
• Пайда болған үрдіс ата-аналық үрдіске үзіліс туралы сигнал жібереді.
• Ата-аналық үрдіс сигналды қабылдайды және сигналды өңдеу функциясын
шақырады, бірақ контекстті ауыстыруды signal функцисы шақырылғанға
дейін ауыстыруды жүзеге асыратын ядромен резервтеленеді.
• Ата-аналық үрдіске үзіліс туралы тағы бір сигнал жіберетін пайда
болған үрдіс қайта іске қосылады.
• Ата-аналық үрдіс үзіліс туралы екінші сигналды қабылдайды, бірақ бұдан
юұрын ол сигналды өңдеу әдісіне қатысты ешқандай нұс-қау беріп
үлгермейді. Ата-аналық үрдістің орындалуы қайта қалпына келген соң ол
аяқталады.
#include signal.h
sigcatcher()
{
printf("PID %d сигнал қабылдады\n",getpid()); *PID басып
шығару*
signal(SIGINT,sigcatcher);
}

main()
{
int ppid;

signal(SIGINT,sigcatcher);

if (fork() == 0)
{
* Үрдіске орнатылу үшін уақыт беру *
sleep(5); * 5 секундқа тоқтату функциясы *

ppid = getppid(); *ата-ананың идентификаторын алу*

for (;;)
if (kill(ppid,SIGINT) == -1)
exit();
}

* приоритеті кіші болған сайн бәсекелестіктің көбею
мүмкіндігі артады *

nice(10);
for (;;)
;
}

5 – сурет. Сигналдарды өңдеу жүрісі кезінде үрдістер арасында бәсеке-
лестіктің пайда болуын көрсететін программа.

Программада үрдістің нақ осындай тәртібі сипатталады, өйткені ата-
аналық үрдістің nice функциясын шақыруынан ядро пайда болған үрдістің
орындалуын іске қосуды жиелетуге әкеледі. Ричидің айтуынша (бұл мәліметтер
жеке әңгімеден алынған), сигналдар оқиға ретінде ойлап табылған. Олар
фатальді болуы да мүмкін, әр уақытта өңделе бермейті байқаусыз өтуі де
мүмкін, сондықтан жүйенің бастапқы версяларында сигналдарды жібрумен
байланысты үрдістердің бәсекелестігі тіркелмеген. Әйтсе де, сигналдарды
қабылдау жүзеге асатын программаларда бұл үлкен шешілмеген мәселеге жатады.
Бұл мәселе егер сигналды сипаттау аймағы ол қабылданған соң тазартылмаса
шешілуші ед. Алайда, бұндай шешілім жаңа мәселені тудырушы еді: егер
түсетін сигнал қабылданса, ал аймақ тазаланған болса, сигналды өңдеу
функциясын салынған жүгіну стекті толитырып тастау мүмкін. Басқа жағынан
алғанда, ядро сигналды өңдеу функциясының мәнін босатуы мүмкін еді,
осылайша типтегі сигналдарды қолданушы бұндай сигналдарды алған не істеу
керектігін көрсеткенші мән бермеу нұсқауын орындайды. Мұндай шешім
ақпаратты жоғалту қаупін тудырады. Өйткені үрдіс қанша сигнал қабылдағанын
білмейтіндей күйде болады. Алайда бұл жағдайда ақпарат үрдіс бір типтес
сигналдардың үлкен мөлшерін, оларды өңдеу мүмкіндігін алудан бұрын алған
жағдайдан қарағанда көп жоғалмайды. BSD жүйесінде, ақырында, үрдістің
сигналдарды қабылдауға тиым салуға мүмкіндігі бар және жүйелік функцияға
жаңадан жүгіну кезінде тиым салуды алып тастау мүмкіншілігі бар. Үрдіс
сигналдарға тиым салуды алып тастаған кезінде ядро үрдіске барлық тиым салу
қойылған мезеттен бастап қалған сигналдарды жібереді. Үрдіс сигналдарды
қабылдаған кезде ядро келесі сигналды қабылдауға сигналды өңдеу функциясы
жұмысын тоқтатқанға шейін автоматты түрде тиым салып отырады. Ядроның
бұндай әрекетінен ақпараттық үзілістерге әсер ететін ядро ретіндегі
аналогиясы байқалады: Ол жаңа үзілістердің пайда болуына келесілердің
өңделу уақытына шейін тиым салады.
Сигналдарды өңдеудің екінші сәйкессіздігі үрдіс рұқсат етілетін үзіліс
приоритетімен тоқтатылып қойғандағы жүйелік функцияның орындалу уақытында
түсетін сигналдарды қабылдаумен байланысты. Сигнал үрдісті тоқтаудан
шығарады (long jump көмегімен), есептеу ритміне көшіреді дәне сигналды
өңдеу функциясын шақырады. Сигналды өңдеу функциясы жұмы-сын тоқтатқанда,
үрдіс жүйелік функциядан оның орындалуының үзілісі туралы хабарлайтын
қатемен шығады. Қате туралы білгеннен кейін қолдану-шы жүйе функциясына
қайта іске қосады. Алайда, бұл әрекет BSD жүйесіндегі секілді ядромен
автоматты орныдалғаны ыңғайлы болар еді.
Үшінші сәйкессіздік үрдіс түскен сигналға мән бермеген жағдайда пай-да
болажды. Егер сигнал үрдіс рұқсат етілетін үзілістік приоритеті бар күйде
тұрған уақытта түссе, үрдіс жаңарады, бірақ long jump-ты орындамайды.
Басқаша айтқанда ядро үрдістің түскен сигналды оның орнындалуы жаңар-ғаннан
кейін ғана мән бермегенін біледі. Үрдісті уақытша тоқтау қалпында қалдырған
жөн болар еді. Бірақ та, ядро сигналды өңдеу функциясының адре-сін
сақтайиын үрдістің кеңстігіне жіберу мезетінде рұқсаттың болмауы мүмкін.
Бұл мәселе сигналды өңдеу функциясының адресін үрдіс кестесіне жазу жолы
арқылы сақтаумен шешілуі мүмкін. Басқа жағынан, үрдіс лезде уақытша тоқтау
күйіне келуі мүмкін (sleep алгоритмі арқылы), егер ол оның жағалануының
қажеттілігі болмағанын білсе. Алайда, қолданбалы үрдістер өзінің жаңаруын
түсіну мүмкіндігі жоқ, себебі ядро жалғастыру шартымен циклдің ішіндегі
sleep алгоритмінің кірісіндегі нүктеде орналасқан (екінші тарау), егер
үрдістің күткен оқиғасы шын мәнінде керек болмағанда үрдісті қайтадан
уақытша тоқтату күйіне келтіреді.
Жоғарыда айтылғанның бәріне қоса, ядроның ұрпақтың жойылуы типіндегі
сигналдарды басқа сигналдар секілді өңделмейтінін айта кеткен жөн. Дербес
жағдайда, үрдіс ұрпақтың жойылуы сигналдың қабылдануы туралы білгенде ол
сигналдың сәйкес үрдіс кестесінің жазу аймағындағы индекациясын өшіреді
және ешқандай нұсқау болмаса, ешқандай сигнал түспегендей әсер етеді.
Ұрпақтың жойылуы сигналды тағайындау үрдісті жаңартудан, мүмкін болатын
приориттеті тоқтатудан тұрады. Егер үрдіс осы сигналды қабылдаса, онда
барлық қалған жағдайда сигналды өңдеу функция-сына жібереді. Бұл жағдайда
мұндай түрдегі сигнал түскен кезде үрдіс оны ескермейді. Соңында егер үрдіс
ұрпақтың жойылуы (death of child) пара-метрлі сигнал (signal) функциясын
шақырса, онда егер ол осындай ұрпақты ұстаса, ядро оған сәйкес сигналды
жібіреді.

1.2 Үрдістер тобы
UNIX жүйесіде үрдістер PID кодымен идентификацияланбағанымен, кейде
жүйе топтар нөмірін үрдістерді идентификациялау үшін қолдануға тура
келеді. Мәселен shell’a тіркеуші түрінде ортақ тегі бар үрдістер бір-
бірімен өзара байланысты, сондықтан да тұтынушы delete не break
пернелерін басса, терминалды түзу кідіріп қалса, барлық осы үрдістер
сәйкес сигналдарды алады. Анық (айқын) оқиғалар түскен кезде жалпы сигналды
алатын бір-бірімен байланысты үрдістердің топтарын идентифика-циялау үшін
ядро үрдістер тобының кодын қолданады. Топтардың коды үрдістер кестесінде
көрсетіледі, бір топтағы үрдістер топтың бірдей кодын алады. Үрдістер
тобының кодына бастапқы мәнді беру үшін, оның кодына үрдістің
идентификациясын теңестіріп, setpgrp жүйесін қолдану керек. Шақыру
функциясының сиснтаксисі:
grp = setpgrp();

мұндағы grp – үрдістер тобының жаңа коды. Үрдіс ұрпағы fork функциясын
орындаған кезде ол өз тегінің тобының кодын жібереді. Операторлық терми-
налды маңызды ерекшеліктері бар үрдісті орындау үшін қолданған setpgrp
функциясына көңіл аудару керек.

1.3 Сигналдарды үрдістермен жіберу
Сигналдарды жіберу үшін үрдістер kill жүйелік функциясын пайдала-нады.
Шақыру функциясының синтаксисі:
kill(pid, signum) .
Мұндағы, жіберілетін сигналдың (сигнал әрекетінің жұмысының облы-сы),
signum – де жіберілетін сигналдың нөмірі көрсетіледі. Pid мәнімен және
орындалатын үрдістердің жиынының арасындағы байланыс келесідей:
kill(pid,signum)

Егер де pid (pid0) оң бүтін сан болса, ядро үрдіске pid идентифика-
торлы сигналды жібереді.
Егер pid (pid=0) тең 0 онда kill функциясын шақырған үрдіспен бір
топқа кіретін үрдістің барлығына да сигнал жіберіледі.
Егер pid (pid=1) тең 1, онда kill функциясын шақырған кезедегі үрдіс
орындалатын, тұтынушының нақты коды сәйкес келетін барлық үрдістерге
жіберіледі. Өте күшті тұтынушының идентификация кодымен орныдалатын болса,
сигнал жіберген үрдіс идентификаторлы үрдістерден басқа үрдістерге
үлестіріледі.
Егер pid0 болса, онда сигнал pid-тің абсолют мәніне тең нөмірлі топқа
кіретін барлық үрдістерге жіберіледі. Егер де жіберілген сигнал өте күшті
тұтынушының идентификатор кодымен орындалса немес бұл үрдістің тұтынушының
идентификатор коды сигнал қабылдайтын үрдістің кодымен сай келмесе, kill
сәтсіз аяқталады.
6 – суретте келтірілген программа негізгі үрдіс алдындағы тақ нөмірі-
нің мәндерін лақтырады және 10 жаңа үрдісті әкеледі (туғызады). Туылған
кезде үрдіс, өз ата-анасының үрдістер тобының нөмірін алады, бірақ циклдің
тақ жүйесінде үрдістер бұл мәнді лақтырады (тастайды). Жүйелік функциялар
өздері кіретін орындалатын үрдістің идентификация кодының мәнін қайтарады,
ал функциясы сигналды алғанда үрдістің орындалуын тоқтатады. Нәтижесінде
ата-аналық үрдіс функциясын қосады (жібіріді) және өзімен бірге бір топқа
кіретін барлық үрдістерге тоқтатылуы туралы сигналды жібереді. Ядро мирасқа
қалған топ нөмірінің мәнін тастамаған 5 жұп, 5 тақ үрдістерге сигнал
жібіреді:

#include signal.h
main()
{
register int i;

setpgrp();
for (i = 0; i 10; i++)
{
if (fork() == 0)
{
* сезгіштік үрдіс *
if (i & 1)
setpgrp();
printf("pid = %d pgrp = %d\n",getpid(),getpgrp());
pause(); *орындауды жүйелік тоқтату функциясы*

}
}
kill(0,SIGINT);
}

6-сурет. setpgrp функциясының қолдану мысалы.

2 Linux операциялық жүйесінің функциялары

2.1 wait() ... жалғасы

Сіз бұл жұмысты біздің қосымшамыз арқылы толығымен тегін көре аласыз.
Ұқсас жұмыстар
Сигналдар. Үрдістермен жұмыс істеуге арналған жүйелік шақырулар
Windows операциялық жүйесінің тарихы
Операциялық жүйелер пәнінен дәрістер
Файлдарды көшіруді сұрау
WINDOWS ТИПТІ ОПЕРАЦИЯЛЫҚ ЖҮЙЕЛЕР
Linux операциялық жүйесіндегі wait()функциясы
Unix операциондық жүйесінің архитектурасы
Информатика пәнінен ДӘРІСТЕР ЖИЫНТЫҒЫ (оқу-әдістемелік құрал)
Массивтерде компоненттер құру
Деректер қоры «Тенисшілер»
Пәндер