А.В. Столяров - Введение в операционные системы (1114673), страница 37
Текст из файла (страница 37)
Ñèñòåìà äàåò âîçìîæíîñòü ôîðìèðîâàíèÿ ñëîæíûõ çàïðîñîâ ê òàêèì îáúåêòàì (ìîæíî, íàïðèìåð, ïîòðåáîâàòüóâåëè÷èòü ïåðâûé ñåìàôîð íà ïÿòü, óìåíüøèòü âòîðîé íà äâà è óìåíüøèòüòðåòèé íà ÷åòûðå − çà îäíî äåéñòâèå). Ïðè ýòîì ãàðàíòèðóåòñÿ àòîìàðíîñòüâñåãî äåéñòâèÿ. Ñëåäóåò îòìåòèòü, ÷òî, â äîïîëíåíèå ê îáû÷íûì îïåðàöèÿì, ñåìàôîðû System V IPC ïîääåðæèâàþò çàïðîñ áëîêèðîâàòü âûçâàâøèéïðîöåññ, ïîêà ñåìàôîð íå îêàæåòñÿ ðàâåí íóëþ. ×èòàòåëü ëåãêî ìîæåò óáåäèòüñÿ, ÷òî çàäà÷è î ïÿòè ôèëîñîôàõ è î ÷èòàòåëÿõ è ïèñàòåëÿõ îêàçûâàþòñÿî÷åíü ëåãêî ðàçðåøèìû ñ ïîìîùüþ ñåìàôîðîâ System V IPC: ïåðâàÿ − áëàãîäàðÿ íàëè÷èþ ìàññèâîâ ñåìàôîðîâ, âòîðàÿ − áëàãîäàðÿ íàëè÷èþ îïåðàöèèäîæäàòüñÿ íóëÿ.Íàäî îòìåòèòü, ÷òî System V IPC íå ïðåäîñòàâëÿåò îòäåëüíûõ îáúåêòîâäëÿ ìüþòåêñîâ, òàê ÷òî ïðè íåîáõîäèìîñòè ïðèõîäèòñÿ èìèòèðîâàòü ìüþòåêñû ñ ïîìîùüþ ñåìàôîðîâ.1 Íåîáõîäèìîîòìåòèòü, ÷òî ýòè îáúåêòû ðàçäåëÿåìîé ïàìÿòè íå èìåþò íè÷åãî îáùåãî ñ òåìè, êîòîðûåìû ïîëó÷àëè âûçîâîì mmap()171Èíòåðôåéñ ñèñòåìíûõ âûçîâîâ System V IPC äîñòàòî÷íî ñëîæåí è ãðîìîçäîê, ïîýòîìó ðàññìàòðèâàòü åãî ìû íå áóäåì.
Ïðè æåëàíèè ÷èòàòåëü ìîæåòèçó÷èòü System V IPC, íàïðèìåð, ñ ïîìîùüþ êíèãè [5].29.1.2Ñåìàôîðû è ìüþòåêñû POSIXÂòîðîé âèä ñåìàôîðîâ, äîñòóïíûé â ÎÑ Unix, âõîäèò â ïîäñèñòåìó óïðàâëåíèÿ ëåãêîâåñíûìè ïðîöåññàìè. Èõ èíòåðôåéñ ãîðàçäî ïðîùå: ïîääåðæèâàþòñÿ òîëüêî îïåðàöèè óâåëè÷åíèÿ è óìåíüøåíèÿ íà 1 (êàê è äëÿ êëàññè÷åñêèõñåìàôîðîâ Äåéêñòðû), îáúåäèíåíèÿ ñåìàôîðîâ â ìàññèâû íåò, êàê è îïåðàöèèäîæäàòüñÿ íóëÿ.Ïîäñèñòåìà ïîääåðæèâàåò êàê ñåìàôîðû, òàê è ìüþòåêñû. Íàäî îòìåòèòü, ÷òî è ñåìàôîðû, è ìüþòåêñû ñóùåñòâóþò â âèäå ïåðåìåííûõ â ïîëüçîâàòåëüñêîì ïðîöåññå; ÿäðî ïîääåðæèâàåò òîëüêî ñîîòâåòñòâóþùèå îïåðàöèèíàä íèìè.Ñòàíäàðò POSIX threads (pthreads) ïðåäóñìàòðèâàåò äîñòóï ê îäíîìó ñåìàôîðó èç ðàçíûõ ïðîöåññîâ, â òîì ÷èñëå è ÷åðåç èìåíà â ôàéëîâîé ñèñòåìå.Îäíàêî ìíîãèå ðåàëüíî ñóùåñòâóþùèå ñèñòåìû (â ÷àñòíîñòè, Linux) ïîääåðæèâàþò ñåìàôîðû POSIX òîëüêî â ðàìêàõ îäíîãî ïðîöåññà äëÿ âçàèìîäåéñòâèÿ â åãî ðàìêàõ ëåãêîâåñíûõ ïðîöåññîâ (ïîòîêîâ).29.2Pthreads: ëåãêîâåñíûå ïðîöåññû â ÎÑ Unix ýòîì ïàðàãðàôå ìû áóäåì äëÿ êðàòêîñòè èñïîëüçîâàòü òåðìèí ïîòîêïðè îáîçíà÷åíèè ëåãêîâåñíûõ ïðîöåññîâ (ðàíüøå ìû íå èñïîëüçîâàëè òàêóþòåðìèíîëîãèþ, ò.ê.
ñëîâî ïîòîê â ïðîãðàììèðîâàíèè èìååò ñëèøêîì ìíîãîçíà÷åíèé). Íàïîìíèì, ÷òî ñîîòâåòñòâóþùèé àíãëîÿçû÷íûé òåðìèí − thread. 1995 ãîäó áûë ïðèíÿò ñòàíäàðò, îïèñûâàþùèé ôóíêöèè óïðàâëåíèÿ ïîòîêàìè, ïîä îáùèì íàçâàíèåì pthreads.  íàñòîÿùåå âðåìÿ ýòîò ñòàíäàðò âòîé èëè èíîé ñòåïåíè ïîääåðæèâàåòñÿ âî âñåõ îïåðàöèîííûõ ñèñòåìàõ ñåìåéñòâà Unix, à òàêæå è â ñèñòåìàõ ëèíèè Windows.Ñîãëàñíî pthreads, ïîòîê äîëæåí èìåòü ãëàâíóþ ôóíêöèþ (àíàëîãè÷íîòîìó, êàê ïðîöåññ èìååò ôóíêöèþ main()) ñëåäóþùåãî âèäà:void* my_thread_main(void *arg) {/* ...
*/}Òàêèì îáðàçîì, ïîòîêó â êà÷åñòâå ñòàðòîâîãî ïàðàìåòðà ìîæíî ïåðåäàòü óêàçàòåëü íà ïðîèçâîëüíóþ îáëàñòü ïàìÿòè (void*); ïîòîê ìîæåò ïðè çàâåðøåíèè ñîîáùèòü äðóãèì ïîòîêàì ðåçóëüòàò ñâîåé ðàáîòû â âèäå, îïÿòü-òàêè,172ïðîèçâîëüíîãî óêàçàòåëÿ. Çäåñü ïðîñëåæèâàåòñÿ íåêîòîðàÿ àíàëîãèÿ ñ îáû÷íûìè ïðîöåññàìè, êîòîðûå ïðè çàïóñêå ïîëó÷àþò â êà÷åñòâå àðãóìåíòà ãëàâíîé ôóíêöèè êîìàíäíóþ ñòðîêó, à ïðè çàâåðøåíèè ôîðìèðóþò ÷èñëîâîé êîäâîçâðàòà.Êàæäûé ïîòîê èìååò ñâîé óíèêàëüíûé èäåíòèôèêàòîð, êîòîðûé ìîæíîñîõðàíèòü â ïåðåìåííîé òèïà pthreads_t.Äëÿ ñîçäàíèÿ (è çàïóñêà) ïîòîêà èñïîëüçóåòñÿ ôóíêöèÿint pthread_create(pthread_t* thr, pthread_attr_t* attr,void*(*start_routine)(void*), void* arg);Ïàðàìåòð thr óêàçûâàåò, â êàêóþ ïåðåìåííóþ ñèñòåìå ñëåäóåò çàïèñàòü èäåíòèôèêàòîð íîâîãî ïîòîêà. Àðãóìåíò attr ïîçâîëÿåò çàäàòü ñïåöèôè÷åñêèåïàðàìåòðû ðàáîòû íîâîãî ïîòîêà; â áîëüøèíñòâå ñëó÷àåâ òàêèå ïàðàìåòðûíå íóæíû, òàê ÷òî ìîæíî â êà÷åñòâå ýòîãî àðãóìåíòà ïåðåäàòü íóëåâîé óêàçàòåëü.
Ïàðàìåòð start_routine óêàçûâàåò íà ãëàâíóþ ôóíêöèþ ïîòîêà.Èìåííî ýòà ôóíêöèÿ áóäåò çàïóùåíà âî âíîâü ñîçäàííîì ïîòîêå, ïðè÷åì íàâõîä åé áóäåò ïåðåäàí óêàçàòåëü, êîòîðûé ïðè âûçîâå pthread_create ìûóêàçàëè â êà÷åñòâå ïàðàìåòðà arg.Ôóíêöèÿ pthread_create âîçâðàùàåò 0 â ñëó÷àå óñïåõà, ëèáî êîä îøèáêè, åñëè ñîçäàòü íîâûé ïîòîê íå óäàëîñü (äëÿ äàííîé ôóíêöèè òàêèì êîäîììîæåò áûòü òîëüêî EAGAIN, êîòîðûé îçíà÷àåò, ÷òî äëÿ ñîçäàíèÿ ïîòîêà íåõâàòèëî ñèñòåìíûõ ðåñóðñîâ, ëèáî áûëî äîñòèãíóòî ïðåäåëüíîå êîëè÷åñòâîïîòîêîâ äëÿ îäíîãî ïðîöåññà).Ïîòîê ìîæåò çàâåðøèòüñÿ äâóìÿ ñïîñîáàìè: âåðíóâ óïðàâëåíèå èç ñâîåé ãëàâíîé ôóíêöèè (ïîäîáíî òîìó, êàê ïðîöåññ âîçâðàùàåò óïðàâëåíèå èçôóíêöèè main()) ëèáî âûçâàâ ôóíêöèþvoid pthread_exit(void *retval); ïåðâîì ñëó÷àå ðåçóëüòàòîì ðàáîòû ïîòîêà ñòàíåò çíà÷åíèå, âîçâðàùåííîåèç ãëàâíîé ôóíêöèè (íàïîìíèì, îíî èìååò òèï void*), âî âòîðîì ñëó÷àå −çíà÷åíèå àðãóìåíòà retval.
Çäåñü ñíîâà ïðîñëåæèâàþòñÿ àíàëîãèè ñ óïðàâëåíèåì ïðîöåññàìè, íà ñåé ðàç − ñ ôóíêöèåé exit().Ïîòîê ìîæåò äîæäàòüñÿ çàâåðøåíèÿ äðóãîãî ïîòîêà ñ ïîìîùüþ ôóíêöèèint pthread_join(pthread_t th, void **result);Àðãóìåíò th çàäàåò èäåíòèôèêàòîð òðåäà, çàâåðøåíèÿ êîòîðîãî ìû õîòèìæäàòü. ×åðåç ïàðàìåòð result ïåðåäàåòñÿ àäðåñ óêàçàòåëÿ òèïà void*, â êîòîðûé ñëåäóåò çàïèñàòü ðåçóëüòàò ðàáîòû ïîòîêà. Ýòî íåñêîëüêî íàïîìèíàåòôóíêöèîíèðîâàíèå âûçîâà waitpid() äëÿ îáû÷íûõ ïðîöåññîâ.173Ðåçóëüòàò âûïîëíåíèÿ çàâåðøåííîãî ïîòîêà äîëæåí ãäå-òî õðàíèòüñÿ; åñëè åãî íå âîñòðåáîâàòü âûçîâîì pthread_join(), îí áóäåò âïóñòóþ çàíèìàòüñèñòåìíûå ðåñóðñû, êàê ýòî ïðîèñõîäèò ñ ïðîöåññàìè (çîìáè).
Îäíàêî äëÿïîòîêîâ ýòîãî ìîæíî èçáåæàòü, ïåðåâåäÿ ïîòîê â îòñîåäèíåííûé ðåæèì(àíãë. detached mode ). Ýòî äåëàåòñÿ ôóíêöèåéint pthread_detach(pthread_t th);Íåäîñòàòîê îòñîåäèíåííûõ ïîòîêîâ â òîì, ÷òî èõ íåâîçìîæíî äîæäàòüñÿ ñïîìîùüþ pthread_join() è, ñîîòâåòñòâåííî, íåò ñïîñîáà ïðîàíàëèçèðîâàòüðåçóëüòàò èõ ðàáîòû.Ôóíêöèè pthread_detach() è pthread_join() âîçâðàùàþò, êàê èpthread_create(), 0 â ñëó÷àå óñïåõà, ëèáî êîä îøèáêè, åñëè âûïîëíèòü äåéñòâèå íå óäàëîñü.Óçíàòü ñâîé ñîáñòâåííûé èäåíòèôèêàòîð ïîòîê ìîæåò ñ ïîìîùüþ ôóíêöèèpthread_t pthread_self();Íàïðèìåð, ïîòîê ìîæåò ïåðåâåñòè ñàìîãî ñåáÿ ââûïîëíèâ âûçîâîòñîåäèíåííûé ðåæèì,pthread_detach(pthread_self());.Ïîòîê ìîæåò äîñðî÷íî çàâåðøèòü äðóãîé ïîòîê, âûçâàâ ôóíêöèþint pthread_cancel(pthread_t th); ýòîì ñëó÷àå ðåçóëüòàòîì ðàáîòû ïîòîêà th áóäåò ñïåöèàëüíîå çíà÷åíèåPTHREAD_CANCELED.Ñëåäóåò îòìåòèòü, ÷òî âûçîâpthread_cancel() íå óíè÷òîæàåò ïîòîê, à îòìåíÿåòåãî, ÷òî,âîîáùå ãîâîðÿ, íå âñåãäà ïðèâîäèò ê íåìåäëåííîìó ïðåêðàùåíèþ âûïîëíåíèÿ äðóãîãî ïîòîêà: âîçìîæíî, ÷òî ïîòîê çàâåðøèòñÿ, òîëüêî äîéäÿ äî âûçîâà îäíîé èç ôóíêöèé áèáëèîòåêèpthread, âõîäÿùåé â ÷èñëî òî÷åê îòìåíû (àíãë.
cancellation points ). Òàêèå ôóíêöèè, êðîìå îñíîâíûõ äåéñòâèé, ïðîèçâîäÿò ïðîâåðêó íà íàëè÷èå çàïðîñà íà îòìåíó äàííîãî ïîòîêà. Ñïèñîêôóíêöèé, ÿâëÿþùèõñÿ òî÷êàìè îòìåíû, ìîæíî óçíàòü èç äîêóìåíòàöèè íà29.3Âpthread_cancel().Ìüþòåêñû pthreadsêà÷åñòâåìüþòåêñîâ pthreads èñïîëüçóåò ïåðåìåííûå òèïàpthreads_mutex_t. Íà÷àëüíîå çíà÷åíèå òàêîé ïåðåìåííîé, ñîîòâåòñòâóþùåå ñîñòîÿíèþ ìüþòåêñ îòêðûò, ñëåäóåò çàäàòü èíèöèàëèçàòîðîìPTHREAD_MUTEX_INITIALIZER, íàïðèìåð:pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;174Âîçìîæíû è äðóãèå, áîëåå ñëîæíûå âàðèàíòû èíèöèàëèçàöèè ìüþòåêñà,â òîì ÷èñëå ñ ïîìîùüþ ñïåöèàëüíîé ôóíêöèè, îäíàêî äëÿ íàøèõ èëëþñòðàòèâíûõ öåëåé äîñòàòî÷íî îäíîãî.
Ñëåäóåò îáðàòèòü âíèìàíèå, ÷òîPTHREAD_MUTEX_INITIALIZER ïðåäñòàâëÿåò ñîáîé èìåííî èíèöèàëèçàòîð,ò.å., âîîáùå ãîâîðÿ, ïîïûòêà ïðèñâîèòü ìüþòåêñó ýòî çíà÷åíèå, ñêîðåå âñåãî, ïðèâåäåò ê îøèáêå ïðè êîìïèëÿöèè (ðåçóëüòàò ìàêðîïîäñòàíîâêè ýòîãîìàêðîñà ìîæåò ñîäåðæàòü ôèãóðíûå ñêîáêè).Íàïîìíèì, ÷òî ïîä ìüþòåêñîì ïîíèìàåòñÿ îáúåêò, ñïîñîáíûé íàõîäèòüñÿâ îäíîì èç äâóõ ñîñòîÿíèé (îòêðûòîì è çàêðûòîì), íàä êîòîðûì îïðåäåëåíû äâå îïåðàöèè: îòêðûòèå (unlock()) è çàêðûòèå (lock()), ïðè÷åì ïåðâàÿâñåãäà ïåðåâîäèò ìüþòåêñ â îòêðûòîå ñîñòîÿíèå è âîçâðàùàåò óïðàâëåíèå,âòîðàÿ æå, åñëè åå ïðèìåíèòü ê îòêðûòîìó ìüþòåêñó, çàêðûâàåò åãî è âîçâðàùàåò óïðàâëåíèå, åñëè æå åå ïðèìåíèòü ê çàêðûòîìó ìüþòåêñó, ìîæåò ëèáîâåðíóòü óïðàâëåíèå, ñèãíàëèçèðóÿ î íåóäà÷å (íåáëîêèðóþùèé âàðèàíò), ëèáîáëîêèðîâàòü âûçâàâøèé ïðîöåññ (èëè, â äàííîì ñëó÷àå, ïîòîê), äîæäàòüñÿ,ïîêà êòî-òî íå îòêðîåò ìüþòåêñ, çàêðûòü åãî è òîëüêî ïîñëå ýòîãî âåðíóòüóïðàâëåíèå (áëîêèðóþùèé âàðèàíò). pthreads îñíîâíûå îïåðàöèè íàä ìüþòåêñàìè îñóùåñòâëÿþòñÿ ñ ïîìîùüþ ôóíêöèéint pthread_mutex_unlock(pthread_mutex_t *mutex);int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_trylock(pthread_mutex_t *mutex);Ýòè ôóíêöèè îñóùåñòâëÿþò, ñîîòâåòñòâåííî, îòêðûòèå ìüþòåêñà (unlock),áëîêèðóþùåå çàêðûòèå ìüþòåêñà (lock) è íåáëîêèðóþùåå çàêðûòèå ìüþòåêñà (trylock).
Âñå ôóíêöèè âîçâðàùàþò 0 â ñëó÷àå óñïåõà, ëèáî íåíóëåâîé êîäîøèáêè, ïðè÷åì â ñëó÷àå, åñëè pthread_mutex_trylock() ïðèìåíÿåòñÿ ê çàêðûòîìó ìüþòåêñó, îíà âîçâðàùàåò êîä EAGAIN.Ìüþòåêñ ìîæíî óíè÷òîæèòü âûçîâîì ôóíêöèèint pthread_mutex_destroy(pthread_mutex_t *mutex);êîòîðàÿ âûñâîáîäèò èñïîëüçóåìûå ìüþòåêñîì ðåñóðñû, åñëè òàêîâûå åñòü (çàìåòèì, â ðåàëèçàöèè ìüþòåêñîâ â ÎÑ Linux âåñü ìüþòåêñ öåëèêîì óìåùàåòñÿâ ïåðåìåííîé pthread_mutex_t, òàê ÷òî âûñâîáîæäàòü îêàçûâàåòñÿ íå÷åãî).Íà ìîìåíò óíè÷òîæåíèÿ ìüþòåêñà îí äîëæåí íàõîäèòüñÿ â ñîñòîÿíèè îòêðûò, èíà÷å ôóíêöèÿ âåðíåò îøèáêó.29.4POSIX-ñåìàôîðûÊàê óæå ãîâîðèëîñü, ñåìàôîðû â ñòàíäàðòå POSIX èçíà÷àëüíî ðàñ÷èòàíûíà âçàèìîäåéñòâèå íåñêîëüêèõ ïðîöåññîâ, â òîì ÷èñëå, âîçìîæíî, íåðîäñòâåí175íûõ. Îäíàêî íåêîòîðûå ñóùåñòâóþùèå ðåàëèçàöèè POSIX-ñåìàôîðîâ (âêëþ÷àÿ, íàïðèìåð, ðåàëèçàöèþ â ÎÑ Linux) äîïóñêàþò èñïîëüçîâàíèå POSIXñåìàôîðîâ òîëüêî â ðàìêàõ îäíîãî ïðîöåññà äëÿ âçàèìîäåéñòâèÿ ïîòîêîâ. êà÷åñòâå ñåìàôîðà èñïîëüçóåòñÿ ïåðåìåííàÿ òèïà sem_t (POSIX ïðåäïîëàãàåò, ÷òî ýòî ìîæåò áûòü ñëîæíàÿ ñòðóêòóðà äàííûõ, íî â ðåàëèçàöèèpthreads â ÎÑ Linux ýòî ïðîñòàÿ öåëî÷èñëåííàÿ ïåðåìåííàÿ, õîòÿ è íå ðàâíàÿçíà÷åíèþ ñåìàôîðà, ïîñêîëüêó ñîäåðæèò ñëóæåáíóþ èíôîðìàöèþ).Èíèöèàëèçàöèÿ ñåìàôîðìà ïðîèçâîäèòñÿ ôóíêöèåéint sem_init(sem_t *sem, int pshared, unsigned int value);Ïàðàìåòð sem çàäàåò àäðåñ èíèöèàëèçèðóåìîãî ñåìàôîðà.
Ïàðàìåòð psharedóêàçûâàåò, áóäåò ëè ñåìàôîð äîñòóïåí äëÿ äðóãèõ ïðîöåññîâ; â ðåàëèçàöèÿõ,êîòîðûå íå ïîääåðæèâàþò òàêóþ ôóíêöèîíàëüíîñòü ñåìàôîðîâ, îí äîëæåíáûòü ðàâåí íóëþ. Íàêîíåö, ïàðàìåòð value çàäàåò íà÷àëüíîå çíà÷åíèå ñåìàôîðà.Êàê ìû ïîìíèì, ñåìàôîð, ïî îïðåäåëåíèþ, åñòü îáúåêò, âíóòðåííåå ñîñòîÿíèå êîòîðîãî ïðåäñòàâëÿåò ñîáîé íåîòðèöàòåëüíîå öåëîå ÷èñëî, è íàä êîòîðûì îïðåäåëåíû äâå îïåðàöèè: up() è down(). Ïåðâàÿ èç íèõ óâåëè÷èâàåòçíà÷åíèå ñåìàôîðà íà 1 è íåìåäëåííî âîçâðàùàåò óïðàâëåíèå. Âòîðàÿ, åñëè çíà÷åíèå ñåìàôîðà ðàâíî íóëþ, áëîêèðóåò âûçâàâøèé ïðîöåññ èëè ïîòîêäî òåõ ïîð, ïîêà êòî-òî äðóãîé íå óâåëè÷èò çíà÷åíèå ñåìàôîðà (åñëè çíà÷åíèå èçíà÷àëüíî íåíóëåâîå, áëîêèðîâêè íå ïðîèñõîäèò), ïîñëå ÷åãî óìåíüøàåòçíà÷åíèå ñåìàôîðà íà 1 è âîçâðàùàåò óïðàâëåíèå.Äëÿ ñåìàôîðîâ POSIX ñîîòâåòñòâóþùèå îïåðàöèè âûïîëíÿþòñÿ ôóíêöèÿìèint sem_post(sem_t *sem);int sem_wait(sem_t *sem);/* up()*//* down() */Òàêæå èìååòñÿ íåáëîêèðóþùèé âàðèàíò îïåðàöèè down():int sem_trywait(sem_t *sem); ñëó÷àå, åñëè ñåìàôîð íà ìîìåíò âûçîâà èìååò çíà÷åíèå 0, ýòà ôóíêöèÿ,âìåñòî òîãî ÷òîáû áëîêèðîâàòü âûçâàâøèé ïðîöåññ, íåìåäëåííî çàâåðøàåòñÿ,âîçâðàòèâ çíà÷åíèå EAGAIN.Ïðè íåîáõîäèìîñòè ìîæíî óçíàòü òåêóùåå çíà÷åíèå ñåìàôîðà ñ ïîìîùüþôóíêöèèint sem_getvalue(sem_t *sem, int *sval);Çíà÷åíèå ñåìàôîðà âîçâðàùàåòñÿ ÷åðåç ïàðàìåòð sval.Íàêîíåö, óíè÷òîæèòü ñåìàôîð ìîæíî âûçîâîì176int sem_destroy(sem_t *sem);Ïðè ýòîì íå äîëæíî áûòü íè îäíîãî ïîòîêà, íàõîäÿùåãîñÿ â ñîñòîÿíèèîæèäàíèÿ íà ýòîì ñåìàôîðå, òî åñòü âûïîëíÿþùåãî â íàñòîÿùèé ìîìåíòsem_wait() ñ òåì æå ïàðàìåòðîì, ÷òî è sem_destroy().