Lemur zaprasza
Do spisu tresci tematu 1 1.5.2 Sygnaly - struktury i funkcje, Stan uspienia procesu Spis tresci Wprowadzenie Dzialanie Typy i struktury danych: wprowadzenie, sigset_t, _sighandler_t, sigaction Pola w strukturze procesu: wprowadzenie, signal, blocked, sig, exit_signal Funkcje wewnetrzne jadra i ich implementacja:wprowadzenie, send_sig(), force_sig(), do_signal(), notify_parent() Funkcje systemowe: wprowadzenie, kill(), sigsuspend(), sigprocmask(), sgetmask(), ssetmask(), sigpending(), signal(), sigaction(), sigreturn() Stan uspienia procesu: wprowadzenie,struktura wait_queue,wake_up(), wake_up_interruptible(), interruptible_sleep_on(), sleep_on() Bibliografia Wprowadzenie Sygnaly sluza do zawiadamiania procesow o wystapieniu pewnych sytuacji wyjatkowych. Jedyna cecha sygnalu odebranego przez proces jest jego numer. Niemozliwe jest stwierdzenie nadawcy sygnalu, liczby wyslanych sygnalow, ani zadnej dodatkowej informacji na jego temat. Stad nazywanie sygnalow mechanizmem komunikacji jest lekka przesada. Za to doskonale nadaje sie on do informowania procesu o sytuacji wyjatkowej (patrz Sygnaly-opis). Dzialanie Proces w momencie otrzymania sygnalu moze znajdowac sie w roznych stanach, przez co roznorodne sa takze jego reakcje na sygnal. Jesli sygnal, ktory jest wysylany, jest zablokowany, to zdarzenia, ktore wymieniam dalej, sa wstrzymywane az do wykonania przez proces odblokowania sygnalu. Gdy proces jest w stanie TASK_INSTERRUPTIBLE jest on budzony z kolejki oczekiwania i jego stan jest ustawiany na TASK_RUNNING (patrz Procesy-stany). W przypadku gdy proces znajduje sie w trybie uzytkownika i jest gotowy do wykonania lub wykonywany TASK_RUNNING (patrz Procesy-stany) to spodziewane, sekwencyjne wykonywanie procesu jest przerywane i wykonywana jest akcja zwiazana z tym sygnalem (patrz Sygnaly-spis). Po zakonczeniu wykonywania akcji zwiazanej z sygnalem proces powraca do miejsca, w ktorym jego dzialanie zostalo przerwane. Gdy proces jest w stanie TASK_RUNNING lecz znajduje sie w trybie jadra (wykonuje jakas funkcje systemowa) to akcja zwiazana z sygnalem jest wykonywana po powrocie z funkcji systemowej a przed wznowieniem programu. Struktury i funkcje, ktore sa tutaj opisane realizuja podana specyfikacje. Typy i struktury danych Wprowadzenie Wiekszosc typow i struktur danych zwiazanych z sygnalami jest zdefiniowana w pliku /asm/signal.h. Sa tam takze zdefiniowane stale zwiazane z numerami sygnalow (patrz Sygnaly-spis). Procz tego znajdziemy tam stale zwiazane ze zdefiniowanymi typami i strukturami danych. Typ sigset_t Definicja typu sigset_t z pliku asm/signal.h: typedef unsigned long sigset_t; /* co najmniej 32 bity */ Typ sigset_t sluzy do trzymania zbioru sygnalow (kazdemu sygnalowi odpowiada dokladnie jeden bit). Jak widac jest to liczba co najmniej 32-bitowa, stad stala ilosci sygnalow definiowana jest w nastepujacy sposob: #define _NSIG 32 #define NSIG _NSIG Typ __sighandler_t Typ __sighandler_t jest to typ funkcji obslugi przerwania zdefiniowany w pliku asm/signal.h nastepujaco: typedef void (*__sighandler_t)(int); Zdefiniowane sa takze stale, standardowe wartosci zmiennych tego typu: #define SIG_DFL ((__sighandler_t)0) /* domyslna obsluga sygnalu */ #define SIG_IGN ((__sighandler_t)1) /* ignorowanie sygnalu */ #define SIG_ERR ((__sighandler_t)-1) /* blad (przy powrocie z funkcji signal) */ Struktura sigaction Oto dokladna definicja struktury sigaction z pliku asm/signals.h: /* jedna struktura sigaction dla kazdego sygnalu */ struct sigacion { _sighandler_t *sa_handler; /* funkcja obslugi sygnalu */ sigset_t sa_mask; unsigned long sa_flags; void (*sa_restorer)(void); }; Dodatkowe wyjasnienia: sa_handler Funkcja obslugi sygnalu (patrz typ _sighandler_t). sa_mask Jest to maska sygnalow ktore maja byc zablokowane zaraz po wolaniu funkcji obslugi a przed rozpoczeciem jej wykonywania (patrz flaga SA_NOMASK) sa_flags Jest to pole flag decydujacych o sposobie obslugi przerwania. Chwilowo dostepne sa nastepujace flagi (stale zdefiniowane w pliku asm/signals.h): SA_NOCLDSTOP decyduje czy zawiadamiac rodzica procesu o jego zatrzymaniu (patrz funkcja notifyparent) SA_SHIRQ dla przerwan dzielonych przez PCI i EISA SA_STACK nie jest jeszcze zaimplementowane, ale w przyszlosci pozwoli na uzywanie oddzielnego stosu do funkcji obslugi sygnalu poprzez uzycie pola sa_restorer (obecnie nieuzywanego) w strukturze sigaction jako wskaznika do stosu SA_RESTART flaga do otrzymania sygnalow restartujacych (w przypadku przerwania dzialania funkcji systemowej przez sygnal z ustawiona flaga funkcja ta jest ponawiana)(ta flaga byla kiedys domyslna) SA_INTERRUPT uzywana jedynie wewnetrznie przez system (obsluga urzadzen zewenetrznych) w przypadku handlerow przerwan sprzetowych SA_NOMASK po wywolaniu handlera nastepne sygnaly nie sa maskowane (ani ten sygnal ani maska sa_mask) SA_ONESHOT po wywolaniu funkcji obslugi sygnalu lecz przed rozpoczeciem jego wykonywania pole sa_handler struktury sigaction jest ustawiane na 0 (obsluga domyslna) SA_PROBE to samo co SA_ONESHOT SA_SAMPLE_RANDOM to samo co SA_RESTART sa_restorer Obecnie przestarzale, nieuzywane pole, ale kiedys moze (patrz flaga SA_STACK). Pola w strukturze procesu Wprowadzenie Struktura procesu zostala dokladnie opisana w proces-struktura procesu. Jednak wiele pol w strukturze procesu dotyczy sygnalow dlatego zostana one tutaj wymienione z krotkim opisem. Struktura procesu jest zdefiniowana w pliku include/linux/shed.h. Pole signal Pole to jest zadeklarowane: unsigned long signal; Maska sygnalow otrzymanych przez proces, ale jeszcze nie obsluzonych. Kazdemu sygnalowi odpowiada jeden bit liczby 32-bitowej. Dlatego niemozliwe jest stwierdzenie ile sygnalow danego rodzaju otrzymal proces. Pole to pokazuje czy proces otrzymal co najmniej jeden sygnal o danym numerze. Z opisu wynika ze proces nie zawsze reaguje natychmiast na przyjscie sygnalu. Ma to miejsce na przyklad gdy dany sygnal jest blokowany (patrz sygnaly-dzialanie). Pole blocked Pole to jest zadeklarowane: unsigned long blocked; Maska sygnalow aktualnie blokowanych przez proces (ich obsluga jest odwlekana). Zapalony bit odpowiadajacy danemu sygnalowi oznacza ze ow sygnal jest blokowany. Mozliwe jest blokowanie wszystkich sygnalow procz SIGKILL i SIGSTOP. Pole sig Pole to jest zadeklarowane: struct signal_struct *sig; gdzie struktura signal_struct jest zadeklarowana w pliku include/linux/shed.h nastepujaco: struct signal_struct { int count; /* licznik dowiazan do struktury */ struct sigaction action[32]; /* akcje zwiazane z poszczegolnymi sygnalami */ }; Pole sig zawiera informacje o akcjach podejmowanych przez proces przy otrzymaniu sygnalu. Jak widac w strukturze signal_struct jest licznik dowiazan do tej struktury-count (handlery sygnalow moga byc wspoldzielone przez kilka procesow a wlasciwie watkow - patrz funkcja-clone). Procz tego struktura zawiera tablice, w ktorej pojedynczy element opisuje akcje zwiazana z sygnalem (patrz struktura-sigaction). Pole exit_signal Pole to jest zadeklarowane: int exit_signal; Pole to zawiera numer sygnalu, ktory ma byc wyslany do rodzica procesu w momencie jego smierci (standardowo wynosi SIGCHLD). Funkcje wewnetrzne jadra i ich implementacja Wprowadzenie Istnieja cztery glowne funkcje systemowe zwiazane z obsluga sygnalow, ktore nie sa dostepne dla zwyklych procesow uzytkownika, ale za to sa uzywane czesto w roznych miejscach w jadrze systemu. Funkcja send_sig() Funkcja ta jest zdefiniowana w /kernel/exit.c. Sluzy do wyslania sygnalu przez aktualny proces. DEFINICJA: int send_sig( unsigned long sig, struct task_struct * p, int priv ) WYNIK: 0 w przypadku sukcesu, lub gdy proces docelowy jest zombie lub sygnal 0 -EINVAL gdy p==0 lub sig>32 -EPERM gdy nie ma przywilejow (priv==0) i to nie jest sygnal SIGCONT lub nie jest z tej samej sesji co p i p->suid i p->uid sa rozne od current->uid i current->euid (maja roznych wlascicieli) i proces wysylajacy nie ma praw zarzadcy systemu Pierwszym argumentem funkcji jest numer sygnalu, ktory ma byc wyslany (musi sie zawierac w przedziale 1..32). Argument p jest wskaznikiem do struktury procesu procesu, do ktorego ma byc wyslany sygnal. Gdy argument trzeci jest niezerowy wtedy niezaleznie od praw aktualnego procesu (proces wysylajacy sygnal) nie bedzie mu zabronione wyslanie sygnalu. Funkcja rozpoczyna swoje dzialanie od sprawdzenia poprawnosci argumentow i czy aktualny proces (current) moze wyslac sygnal do procesu p. Z definicji funkcji wynika iz wyslanie sygnalu jest dozwolone (funkcja nie zwraca -EPERM) gdy jest spelniony jeden z nastepujacych warunkow: argument prev jest niezerowy (proces ma przywileje) wysylany jest sygnal SIGCONT i procesy nadawcy oraz adresata naleza do tej samej sesji ktorys z atrybutow uid lub suid procesu adresata (p) jest rowny ktoremus z atrybutow uid lub euid procesu nadawcy (w uproszczeniu, gdy procesy maja tego samego wlasciciela)(patrz procesy-struktura) proces nadawcy ma przywilej superuser'a. Nastepnie sprawdzane jest czy sygnal sig to jeden z sygnalow budzacych (SIGKILL lub SIGCONT). Jesli tak i proces jest zatrzymany (TASK_STOPPED)(patrz proces-stany) to proces jest budzony. Procz tego ustawiany jest kod wyjscia procesu na 0 (exit_code) i zerowane sa w polu signal procesu bity odpowiadajace sygnalom ktore moglyby zatrzymac proces (sa to: SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU)(patrz sygnaly-spis). Jesli natomiast sygnal sig to jeden z sygnalow, ktore moglyby spowodowac zatrzymanie procesu (sa to: SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU)(patrz sygnaly-spis) to w polu signal procesu p zerowany jest bit odpowiadajacy za sygnal budzacy SIGCONT (patrz sygnaly-spis). Jesli sygnal sig nie jest blokowany ani proces p nie jest sledzony (tj. gdy sygnal moze byc obsluzony natychmiast) to: gdy obsluga sygnalu to ignorowanie(SIG_IGN)(patrz typ-sighandler) i sygnal to SIGCHLD (patrz sygnaly-spis) nastepuje powrot z funkcji z rezultatem 0. Podobnie jest w przypadku gdy obsluga sygnalu jest domyslna (SIG_DFL)(patrz typ-sighandler) a sygnal to jeden z: SIGCONT,SIGCHLD,SIGWINCH,SIGURG. Nastepnie gdy jeszcze nie zakonczono funkcji w polu signal procesu docelowego p ustawiany jest bit odpowiadajacy za sygnal wysylany sig. Dodatkowo gdy proces jest w stanie TASK_INTERRUPTIBLE (patrz proces-stany) i sygnal nie jest blokowany, proces p jest budzony. Funkcja zwraca 0. Funkcja force_sig() - sluzy do bezwarunkowego wysylania sygnalu. DEFINICJA: void force_sig( unsigned long sig, struct task_struct *p ) WYNIK: brak Pierwszym argumentem funkcji jest numer wysylanego sygnalu. p to wskaznik do struktury procesu procesu docelowego. Gdy proces docelowy jeszcze istnieje, w polu signal (patrz proces-struktura) jego struktury jest ustawiany bit odpowiadajacy za sygnal sig, a w polu blocked ten sam bit jest zerowany (to zapewni, ze sygnal zostanie obsluzony od razu po pobraniu procesu do wykonania). Gdy obsluga sygnalu jest ustawiona na ignorowanie (SIG_IGN) to przestawiana jest na obsluge domyslna (SIG_DFL)(patrz typ-sighandler). W przypadku gdy proces p jest w stanie TASK_INTERRUPTIBLE jest on budzony. Funkcja do_signal() - sluzy do obslugi komunikatow ktore przyszly do procesu aktualnego (current), ale jeszcze nie zostaly obsluzone (ustawione bity na polu signal-patrz pole-signal). Funkcja ta jest wolana jedynie w momencie wyjscia z funkcji systemowej a takze w funkcji systemowej sigsuspend(). Wynika z tego, ze sygnaly sa obslugiwane jedynie w momencie wyjscia z funkcji systemowej. DEFINICJA: int do_signal( unsigned long oldmask, struct pt_regs *regs ) WYNIK: 0 w przypadku gdy nie obsluzono zadnego sygnalu 1 gdy obsluzono jeden sygnal Pierwszym argumentem jest stara maska sygnalow (sprzed wywolania handlera). Drugi argument to zachowane na stosie wartosci rejestrow procesora sprzed wywolania funkcji systemowej. Dzialanie funkcji mozna przedstawic za pomoca nastepujacego pseudoalgorytmu: { while (istnieje jeszcze nie obsluzony sygnal nie blokowany) { signr=numer takiego sygnalu i bit sygnalu zerowany; sa=struktura sigaction odpowiadajaca za sygnal signr; if ( ( proces jest sledzony )&&( signr to nie SIGKILL ) ) { stan procesu ustalany na TASK_STOPPED , kod wyjscia /*exit_code*/ na signr; notify_parent(current); shedule(); if(!(signr=aktualny kod wyjscia procesu /*exit_code*/)) continue; kod wyjscia procesu /* exit code */ = 0; if( signr = SIGSTOP ) continue; if( sygnal signr jest blokowany ) ustawiany jest bit tego sygnalu /*w polu signal procesu*/ , continue; sa=struktura sigaction odpowiadajaca za sygnal signr; } if ( w sa handler jest ustawiony na ignorowanie ) { if ( signr to nie SIGCHLD ) continue; while ( sys_waitpid(-1,NULL,WNOHANG) > 0) ; /* wszystkie dzieci zombie usuwane */ continue; } if ( w sa handler syganalu ustawiony na obsluge domyslna ) { if ( czy to proces init ) continue; switch (signr) { case SIGCONT: case SIGCHLD: case SIGWINCH: continue; case SIGTSTP: case SIGTTIN: case SIGTTOU: if ( grupa procesu jest osierocona /* is_orphaned_pgrp */ ) continue; case SIGSTOP: if ( proces jest sledzony ) continue; stan procesu ustawiany na TASK_STOPPED, kod wyjscia na signr; if ( czy obsluga sygnalu SIGCHLD u rodzica ma ustawione zawiadamianie o zatrzymaniu dziecka ) notify_parent(); schedule(); continue; case SIGQUIT: case SIGILL: case SIGTRAP: case SIGABRT: case SIGFPE: case SIGSEGV: zrzut na dysk obrazu procesu /*CORE DUMP*/; default: signal|=bit sygnalu numer ( signr & 0x7f ); w strukturze procesu ustawiona flaga zabicia przez sygnal; do_exit(signr); } /* case */ } /* if */ obsluga sygnalu signr handlerem sa z maska oldmask i rejestrami regs; return 1; } return 0; } Funkcja notify_parent() - wolana gdy nalezy poinformowac rodzica jakiegos procesu o jego zatrzymaniu lub zakonczeniu. DEFINICJA: void notify_parent( struct task_struct *tsk ) WYNIK: brak Argumentem funkcji jest struktura procesu, ktory zmienil stan i chce poinformowac rodzica. Funkcja rozpoczyna swoje dzialanie od sprawdzania czy rodzicem procesu jest Init. Jesli tak, to pole exit_signal procesu tsk jest ustawiane na SIGCHLD. Po tym do procesu rodzica wysylany jest sygnal exit_signal (funkcja send_sig z przywilejami ustawionymi). Nastepnie kolejka czekajacych na smierc tego procesu jest budzona. Funkcje systemowe Wprowadzenie Funkcje systemowe opisane ponizej wystepuja w zrodlach pod podanymi nazwami z dodanymi przedrostkami sys_. Wiele z nich korzysta z funkcji wewnetrznych jadra podanych powyzej. Funkcja kill() - sluzy do wysylania sygnalu. DEFINICJA: int kill( int pid, int sig ) WYNIK: 0 w przypadku sukcesu -1 gdy nastapil blad; wtedy errno przybiera nastepujace wartosci: EINVAL bledny parametr (nr sygnalu) ESRCH nie znaleziony proces do zabicia EPERM peoces nie posiada praw do wykonania tej funkcji Drugim argumentem funkcji jest numer sygnalu, ktory ma byc wyslany do procesu lub grupy procesow opisanych przez pierwszy argument. W zaleznosci od wartosci argumentu pid zmienia sie adresat: gdy pid= 0, wysylany jest sygnal do grupy aktualnego procesu gdy pid=-1, wysylany jest sygnal do wszystkich procesow procz wlasnego (proby wysylania) gdy pid<-1, wysylany jest sygnal do grupy -pid gdy pid> 0, wysylany jest sygnal do procesu o numerze pid Niezaleznie od rodzaju parametrow funkcja korzysta z funkcji jadra send_sig z parametrem perm rownym 0. Stad blad EPERM wystapi tylko wtedy, gdy wystapilby w przypadku wywolania funkcji send_sig. Funkcja sigsuspend() - sluzy do ustawiania maski sygnalow blokowanych i oczekiwania na nadejscie ktoregos z sygnalow nieblokowanych. DEFINICJA: int sigsuspend( unsigned long set ) WYNIK: -1 z errno ustawionym na EINTR Argumentem funkcji jest maska blokowania sygnalow. Dzialanie funkcji: { mask=aktualna maska blokawania sygnalow; ustaw maske blokowania sygnalow na set; while (1) { ustaw stan procesu na TASK_INTERRUPTIBLE; schedule(); if ( do_signal(mask,...) ) return -1(EINTR); } } Funkcja sigprocmask() - sluzy do ustawiania maski blokowania sygnalow. DEFINICJA: int sigprocmask( int how, sigset_t *set , sigset_t *oset ) WYNIK: 0 w przypadku sukcesu -1 gdy wystapil blad; ustawia ERRNO na: EINVAL gdy how mialo wartosc nieznanej opcji; Pierwszym argumentem funkcji jest numer sposobu ustawiania maski. Moze przybrac wartosc jednej ze stalych zdefiniowanych w asm/signal.h: #define SIG_BLOCK 0 /* blokowanie sygnalow */ #define SIG_UNBLOCK 1 /* odblokowywanie sygnalow */ #define SIG_SETMASK 2 /* ustawianie nowej maski */ Argument set jest wskaznikiem na nowa maske blokowania sygnalow. Gdy wskaznik oset jest niezerowy to jest tam wpisywana stara maska blokowania syganlow sprzed wywolania tej funkcji. Funkcja sgetmask() - pobiera maske blokowania sygnalow. DEFINICJA: int sig( ) WYNIK: maska blokowania sygnalow Funkcja ssetmask() - ustawia maske blokowania sygnalow. DEFINICJA: int ssetmask( int newmask ) WYNIK: poprzednia maska blokowania sygnalow Funkcja sigpending() pobiera zbior wstrzymywanych (przez maske blokowania) sygnalow . DEFINICJA: int sigpending( sigset_t *set ) WYNIK: 0 w przypadku sukcesu -1 gdy nastapil blad zapisu pod adres set Zbior blokowanych sygnalow jest wstawiany pod set. Funkcja signal() ustawia nowa procedure obslugi sygnalu. DEFINICJA: _sighandler_t signal( int signum , _sighandler_t handler ) WYNIK: poprzedni handler obslugi tego sygnalu w przypadku sukcesu SIG_ERR gdy nastapil blad Argument signum oznacza numer sygnalu, a handler to nowa procedura obslugi sygnalu (patrz typ _sighandler_t). Funkcja sigaction() ustawia nowa akcje zwiazana z danym sygnalem. DEFINICJA: int sigaction( int signum , const struct sigaction *action , struct sigaction *oldaction) WYNIK: 0 w przypadku sukcesu -1 gdy nastapil blad (errno=EINVAL) Ustawia nowa akcje action zwiazana z sygnalem signum. Stara akcja zwiazana z tym sygnalem jest wpisywana na oldaction. Oba parametry sa typu struct sigaction. Funkcja sigreturn() jest wywolywana przy powrocie z procedury obslugi handlera sygnalu. DEFINICJA: int sigreturn( ) WYNIK: brak Funkcja powinna byc wywolywana przy powrocie z kazdej procedury obslugi sygnalu. Stan uspienia procesu Wprowadzenie Biorac pod uwage definicje stanu uspienia z ksiazki Bacha (patrz Bibliografia) najblizszy temu opisowi wydaje sie stan TASK_INTERRUPTIBLE (patrz proces-stany). Jest to taki stan zatrzymania procesu, ktory moze byc przerwany przez sygnal. Procesy przebywajace w tym stanie sa w wiekszosci przypadkow zatrzymane na strukturze kolejki oczekiwania (struct wait_queue). Do usypiania i budzenia calych kolejek oczekiwania sluza funkcje opisane ponizej. Struktura wait_queue Definicja typu sigset_t z pliku linux/wait.h: struct wait_queue { struct task_struct * task; struct wait_queue * next; }; Na pojedynczej strukturze tego typu sa wstrzymywane wszystkie procesy, ktore maja byc obudzone w przypadku wystapienia zdarzenia z pewnej grupy zdarzen. Funkcja wake_up() Funkcja wake_up jest zaimplementowana w pliku linux/kernel/sched.c. DEFINICJA: void wake_up( struct wait_queue **q ) WYNIK: brak Funkcja budzi wszystkie procesy znajdujace sie na kolejce oczekiwania a bedace w stanie TASK_INTERRUPTIBLE lub TASK_UNINTERRUPTIBLE. Budzenie procesu polega na ustawieniu stanu procesu na TASK_RUNNING i wlozeniu go do kolejki procesow gotowych. O usuniecie z kolejki oczekiwania zadba sam proces obudzony. Funkcja wake_up_interruptible() Funkcja wake_up_interruptible jest zaimplementowana w pliku linux/kernel/sched.c. DEFINICJA: void wake_up_interruptible( struct wait_queue **q ) WYNIK: brak Funkcja budzi wszystkie procesy znajdujace sie na kolejce oczekiwania a bedace w stanie TASK_INTERRUPTIBLE. Budzenie procesu polega na ustawieniu stanu procesu na TASK_RUNNING i wlozeniu go do kolejki procesow gotowych. O usuniecie z kolejki oczekiwania zadba sam proces obudzony (czyli jak wyzej). Funkcja interruptible_sleep_on() Funkcja interruptible_sleep_on jest zaimplementowana w pliku linux/kernel/sched.c. DEFINICJA: void interruptible_sleep_on( struct wait_queue **q ) WYNIK: brak Funkcja usypia proces aktualny na kolejce q ustawiajac jego stan na TASK_INTERRUPTIBLE. Funkcja rozpoczyna dzialanie od dodania procesu aktualnego do kolejki q i ustawieniu stanu procesu na TASK_INTERRUPTIBLE. Nastepnie wywolywana jest funkcja schedule() zmiany procesu aktualnego. Po obudzeniu procesu jest on usuwany z kolejki q. Funkcja sleep_on() Funkcja sleep_on jest zaimplementowana w pliku linux/kernel/sched.c. DEFINICJA: void sleep_on( struct wait_queue **q ) WYNIK: brak Funkcja usypia proces aktualny na kolejce q ustawiajac jego stan na TASK_UNINTERRUPTIBLE (patrz wyzej). Bibliografia Pliki zrodlowe Linuxa 2.0.20: include/asm/signal.h (definicje stalych i typow) include/linux/wait.h (definicje stalych i typow) kernel/signal.c (implementacja) linux/arch/i386/kernel/signal.c (implementacja) linux/kernel/exit.c (implementacja) linux/kernel/sched.c (implementacja) W. Richard Stevens: Programowanie zastosowan sieciowych w systemie UNIX Maurice J. Bach: Budowa systemu operacyjnego UNIX Autor: Rafal Bledzinski |