Linux jest systemem wielozadaniowym, który umożliwia wykonywanie wielu poleceń jednocześnie. Egzekucja polecenia jest identyfikowana przez system przy pomocy numeru identyfikacyjnego PID przypisanego każdemu procesowi, który jest egzekwowany (egzekucja polecenia uruchamia proces). System otrzymując od użytkownika polecenie, uruchamia je, czekając na jego zakończenie. O takim poleceniu mówimy, że jest pierwszoplanowe (foreground). Terminal jest zablokowany do momentu zakończenia zadania. Wyobraźmy sobie (a nie jest to bynajmniej rzadkie), że wykonanie naszego polecenia (np. polecenia find) może trwać wiele minut (są zadania, które trwają wiele godzin). Rzecz jasna możemy zalogować się na innej konsoli wirtualnej i tam możemy uruchamiać kolejne zadania. Innym sposobem postępowania z „długotrwałymi” zadaniami jest uruchamianie ich w tle. Zadanie uruchamiamy jako drugoplanowe wpisując na końcu linii poleceń znak ampresand   & .

Objaśnijmy raz jeszcze mechanizm, który opisaliśmy powyżej: powłoka systemu operacyjnego otrzymując od użytkownika polecenie uruchamia je i czeka na zakończenie jego egzekucji. Tego typu proces nazywamy zadaniem pierwszoplanowym. Uruchamianie poleceń, skryptów pierwszoplanowych nazywa się w języku programistów – domyślnymi, nie jest to najszczęśliwszy termin, gdyż wprowadza wiele zamieszania, szczególnie u początkujących informatyków, dlatego w naszym podręczniku będziemy używali terminu: zadania pierwszoplanowe.

Zauważmy, że wprowadziliśmy przed chwilą nowy termin, którego definicji czytelnik jeszcze nie zna, chodzi o termin: zadanie. Jaka jest różnica miedzy procesem i zadaniem ?

Takie terminy jak właśnie proces czy program lub skrypt mają swoje konkretne znaczenie techniczne i są precyzyjnie osadzone w kontekście budowy i funkcjonowania systemu operacyjnego. Termin  zadanie jest natomiast terminem organizacyjno-technicznym, ponieważ jest on powiązany z pracą użytkownika systemu. Na przykład uruchomienie edytora tekstowego vi jest konkretnym procesem w systemie, ale też jednocześnie zadaniem użytkownika, który realizuje swój cel – napisanie tekstu. Innymi słowy można zadanie określić jako zlecenie systemowi przez użytkownika określonego działania. Użytkownik patrzy i ocenia system operacyjny (ale także np. język programowania) przez pryzmat możliwych do wykonania zadań. Zadanie jest zazwyczaj równoważne z pojedynczym procesem, ale na potrzeby wykonania zadania system operacyjny może uruchomić dodatkowe procesy. Termin  zadanie nie ma definicji ściśle technicznej – jak program czy proces – i dlatego może być on używany w innych kontekstach.

Wiemy już, że niektóre zadania mogą być wykonywane bardzo długo (można je nazwać zadaniami „długotrwałymi”), dlatego Linux dysponuje mechanizmem ich uruchamiania w tzw.  tle lub uruchamiania ich jako  zadań drugoplanowych. Zadania pierwszoplanowe w danej chwili na konkretnej konsoli wirtualnej, możemy uruchomić jedno, natomiast zadań drugoplanowych wiele. Wiemy już, że zadanie drugoplanowe uruchamiamy wpisując na końcu linii poleceń znak ampersand  &. Odpowiednimi poleceniami – z którymi zapoznamy się w tym rozdziale  - możemy również przenosić zadania z planu pierwszego na drugi lub odwrotnie. Aby  zobaczyć zadania działające w danym momencie w tle czyli jako zadania drugoplanowe musimy użyć polecenia   jobs . Polecenie to posiada następujące opcje:

 

-l wyświetlamy także numer PID procesów

-p wyświetlamy tylko numery PID procesów

-n pozwala na wyświetlenie tylko zawieszonych zadań

 

Przykład: wiemy z rozdziału II, że polecenie  ls –R  / wyświetla na ekranie wszystkie katalog i pliki w systemie operacyjnym, a z tego wniosek, ze zapełnione ekrany wyświetlane są bardzo długo. Wykonajmy to polecenie, a następnie zatrzymajmy jego egzekucje przy pomocy klawiszy CTRL+Z.

$  ls  -R  /

Z^

 

W tej chwili wiemy, że zawiesiliśmy wykonywanie polecenia ls  –R /, jeżeli wykonamy w tej chwili polecenie jobs , to rezultaty jego będą następujące:

$  jobs

[1]+   Stopped      ls –R /

 

Liczba w nawiasie kwadratowym (w tym przypadku [1]) oznacza numer zadania użytkownika. Korzystając  z tego numeru, użytkownik może odwoływać się do zadania użytkownika w poleceniach   fg  ,  bg  i kill , które będą  poniżej wyjaśnione. Jednak w tej chwili wykonajmy polecenie   ls –R  / w tle. Jak to zrobić ? Rezultat polecenia – czyli wyświetlające się stronice informacji – umieśćmy w pliku  rezultat korzystając z mechanizmu przekierowania, a na końcu polecenia wystukajmy znak & :

$  ls –R /  > rezultat  &

[1]     456

 

Liczba   456 oznacza identyfikator procesu  PID w systemie. PID jest najczęściej wykorzystywany w poleceniu kill, które omówimy w następnym podrozdziale. Wiemy także że identyfikator (numer) procesu możemy poznać stosując polecenie  jobs z opcją –l. Proces zatrzymany (ang – stopped ) kombinacja klawiszy  CTRL + Z może być wznowiony. Do ponownego uruchomienia zatrzymanego zadania na pierwszym planie używamy polecenia   fg. Do ponownego uruchomienia zatrzymanego zadania na drugim planie – czyli w tzw. tle – używamy polecenia  bg.

Przez ponowne uruchomienie – i jest to bardzo ważna uwaga – rozumiemy sytuacje, w której proces rozpoczyna kontynuacje zadania od miejsca, w którym został zatrzymany.

Jak już powiedzieliśmy zadanie działające w tle można przenieść na pierwszy plan za pomocą polecenia fg . Składnia polecenia  fg pozwala odwołać się do zadania za pomocą znaku  % i numeru zadania. Przykładowo poniższa sekwencja rozpoczyna egzekucje  polecenia  ls –R / w tle:

$  ls –R /  &

[5] 4321

$

 

$ fg %5

$ ls –R /


 

Odwrotnością polecenia  fg jest polecenie  bg. Pozwala ono na przeniesienie zadania uruchomionego na pierwszym planie na drugi plan. Jednak aby to zrobić trzeba przy pomocy kombinacji klawiszy CTRL + Z zawiesić zadanie, w ten sposób przywracamy znak gotowości i możliwość wystukania nowego polecenia.

Jak już wiemy kiedy proces zostanie rozpoczęty, domyślnie działa na tzw. pierwszy planie. Na pierwszym planie staje się jedynym zadaniem, które użytkownik może wykonywać. Kiedy użytkownik wydaje na przykład polecenie ls –l /, wyniki pojawiają się na jego terminalu, a użytkownik nie może wydać innego polecenia, zanim ls –l / nie zakończy swego działania.

Aby uruchomić proces w tle wystarczy umieścić na końcu polecenia znak  & - pozwala to na jednoczesne wykonywanie więcej niż jednego polecenia. Można również wydać polecenie   sleep , które wstrzymuje wykonywanie polecenia w tle na określona ilość sekund.

$  sleep  180  &

[10]  4010

$

 

Liczba pojawiająca się w nawiasie to liczba zadań w danej chwili wykonywanych w tle. Liczba po niej – w tym przypadku 4010 – to identyfikator procesu PID tego zadania.

Umieszczenie zadania w tle pozwala użytkownikowi kontynuować i rozpoczynać inne procesy, to znaczy daje mu możliwość zarządzania procesami wywoływanymi głownie przez niego samego. Jeśli musimy zaczekać na zakończenie jednego procesu przed rozpoczęciem kolejnego procesu to używamy do tego celu polecenia   wait , który w połączeniu z PID procesu, może przerwać przetwarzanie do zakończenia określonego procesu. Na przykład: 

$  sleep  360  &

[6]   5432

$

$  wait   5432 #  znak gotowości $ nie wraca, o ile 5432 to prawidłowy Identyfikator PID

 

Jeszcze jeden mechanizm związany z egzekucją poleceń i związanych z nimi procesów jest niezwykle istotny dla pracy programisty, otóż procesy mogą kontynuować swoją prace nawet po odłączeniu się (wylogowaniu z maszyny). Polecenie które pozwala po wylogowaniu się kontynuacje wykonywania procesów, nazywa się  nohup

$ nohup  dzien

4321

 

Nazwa nohup jest skrótem od  słów „no hung up” – nie rozłączaj. Polecenie zapobiega zakończeniu procesu w momencie wylogowania użytkownika. Komunikaty które są tworzone w trakcie wykonywania tego polecenia skierowane są do pliku o nazwie  nohup.out, który można obejrzeć w celu sprawdzenia wyniku działania polecenia.

 

 

Zarządzanie procesami i zadaniami Rozdział 7.1 Darmowy kurs Linux