|
|
Bu makalenin farkl� dillerde bulundu�u adresler: English Castellano ChineseGB Deutsch Francais Italiano Nederlands Russian Turkce Polish |
taraf�ndan Leonardo Giordani <leo.giordani(at)libero.it> Yazar hakk�nda: Yazar, Milan Politecnico �niversitesinin Telekomunikasyon M�hendisli�inde
okumakta ve bilgisayar a�lar� y�neticisi olarak �al��maktad�r. Daha �ok
Assemble ve C/C++ olmak �zere, programlamaya ilgi duymaktad�r. 1999 y�l�ndan beri
neredeyse tamamen Linux/Unix ile �al��maktad�r.
|
�zet:
Bu yaz� dizisinin amac�, okuyculara Linux i�letim sistemindeki �oklui�lem (multitasking) ve uygulamas�na giri� olu�turmaktad�r. �oklui�lem teorisinin temellerinden ba�layarak, i�lemler veya s�re�ler (processes) aras�ndaki haberle�meyi, basit ve bir o kadar da etkili bir protokol kullanarak g�steren, bir program yazarak konuyu tamamlayaca��z. Yaz�y� anlayabilmek i�in gerekli �nbilgiler �unlard�r:
Birden fazla program� ayn� anda �al��t�rabilmek i�in i�letim sisteminin yapmas� gereken karma��k i�lemlere gereksinimi vard�r. �al��an programlar aras�nda olu�abilecek kar���kl��� �nlemek i�in, programlar�n �al��t�r�lmalar� ile ilgili gerekli t�m bilginin bir yerde saklanmas� ka��n�lmazd�r.
Linux bilgisayar�m�zda ne olup bitti�ine ge�meden �nce biraz genel k�lt�r bilgisi verelim: �al��an bir PROGRAM verildi�inde, program� olu�turan komutlar k�mesine CODE(Program kodu), program verilerin bilgisayar belle�inde kaplad��� alana MEMORY SPACE(Bellek alan�) ve mikroi�lemcinin parametre de�erleri, �e�itli bayrak de�erleri veya program sayac�na (Bir sonra �al��t�r�lacak olan komutun adres de�eri.), PROCESSOR STATUS (�lemci durumu) denilmektedir.
RUNNING PROGRAM (�al��an program) kavram�n�, Program kodu, Bellek alan� ve ��lemci durumu nesnelerinden olu�an bir b�t�n olarak tan�ml�yoruz. E�er, herhangi bir zaman diliminde, bu bilgiyi kaydedip, ba�ka program�n bilgileri ile de�i�tirdi�imizde, kaydetti�imiz programa tekrar d�n�ld���nde, program kald��� yerden �al��mas�na devam edebilmedir: Bu �al��ma y�ntemi birden fazla program�n ayn� anda ve birbirleri ile �ak��madan �al���yor gibi g�r�nmesini sa�lamaktad�r. PROCESS veya TASK (S�re� veya i�lem) kelimesi b�yle �al��an bir program� tan�mlamak i�in kullan�lmaktad�r.
�imdi, yaz�n�n ba��nda s�z�n� etti�imiz Linux bilgisayar�nda neler oldu�una bir g�z atal�m. Herhangi bir anda, bilgisayarda sadece bir adet i�lem �al��t�r�labilmektedir (Sistemde sadece bir mikroi�lemci vard�r ve bu i�lemci ayn� anda iki i�lemi yerine getirememektedir.). �al��an program�n da saedece belli bir k�sm� i�lem g�rmektedir. Belli bir s�re sonra, buna QUANTUM denmektedir, �al��an i�lem durdurulmakta, daha sonra kald��� yerden devam etmek �zere i�lem ile ilgili bilgiler bir yerde ve beklemekte olan ba�ka bir i�lemin bilgileri ile de�i�tirilerek, bir quantum s�resi boyunca �al��t�r�lmaktad�r. Ayn� anda �al���yor gibi izlenim veren i�lemler b�ylece �al��t�r�lmaktad�r. Buna biz multitasking (�oklui�lem) diyoruz.
Daha �nce de s�yledi�im gibi, �oklui�lem kullan�l�yor olmas� baz� sorunlar� da beraberinde getirmektedir. S�zgelimi, kuyrukta bekleyen i�lemlerim y�netimi (SCHEDULING). Herneyse, bunlar i�letim sisteminin yap�s� ile ilgili konular. Bu belkide ba�ka bir yaz� yaz�m� i�in uygun bir konu olabilir. Linux �ekirde�ini tan�t�c� bir yaz� yaz�labilir.
Bilgisayar�m�zda �al��an i�lemler ile ilgili biraz bilgi edinelim. Bu bilgiyi sa�layan komutun ad� ps(1) dir ve "process status" (i�lem durumu) s�zc�klerin k�saltmas�d�r. Bir terminal a��p, ps komutunu �al��tr�rsan�z, a�a��dakine benzer bir ��kt� elde edersiniz.
PID TTY TIME CMD 2241 ttyp4 00:00:00 bash 2346 ttyp4 00:00:00 ps
Daha �nce de belirti�im gibi bu ��kt� tam de�il, ancak �imdilik buna odaklanal�m: ps komutu bize terminalde �al��an i�lemlerin listesini vermektedir. ��kt�n�n son s�t�nunda, i�lemin �al��t�r�ld��� komutun ad�n� g�rmekteyiz. S�zgelimi, Mozilla sanaldoku gezgini i�in mozilla, GNU derleyicisi i�in gcc vs. �al��makta olan i�lemlerin listesi ekranda g�sterilirken ps i�lemi de �al��t���ndan, kendisin de bu listede g�r�nmesi �ok do�al. Listede g�r�nen di�er i�lemler �unlard�r: Benim terminalde �al��an Bourne Again Shell (kabuk ortam�) dir.
Bir an i�in TIME ve TTY bilgilerini g�zard� edelim ve PID (i�lem numaras�) bilgisine bakal�m. Pid, her i�leme tekil olarak verilen, s�f�rdan farkl� pozitif bir say�d�r. ��lem sona erdi�inde, i�lem numaras� tekrar kullan�labilir. Ancak, i�lem �al��t��� s�rece, bu numaran�n deyi�meyece�i garantilenmektedir. Sizin ps komutundan elde edece�iniz ��kt�, yukar�dakinden farkl� olacakt�r. S�ylediklerimin do�rulu�unu s�namak i�in, ba�ka bir terminal a��p orada ps komutunu �al��t�rd���n�zda ayn� listeyi elde edeceksiniz, ancak bu sefer i�lem numaralar� farkl� olacakt�r. Bu da, �al��an i�lemlerin birbirlerinden farkl� olduklar�n� g�stermektedir.
Linux makinam�zda �al��an t�m i�lemlerin listesini elde etmek de m�mk�nd�r. ps komutunun man sayfas�na g�re, -e parametresi, t�m i�lemleri se�mek i�in kullan�lmaktad�r. �imdi bir terminalde "ps -e" komutunu �al��t�ral�m. Elde edece�imiz liste, yukar�daki bi�imde, ancak �ok daha uzun olacakt�r. Listeyi daha rahat bir �ekilde incelebilmek i�in ps komutunun ��kt�s�n� ps.log dosyas�na y�nlendirelim:
ps -e > ps.log
Olu�an dosyay�, tercih etti�iniz herhangi bir kelime i�lemci veya en basitinden less komutu yard�m�yla inceleyebilirsiniz. Yaz�n�n ba��nda da s�z�n� etti�im gibi, �al��an i�lem say�s�, tahmin etti�mizden daha fazlad�r. Ayr�ca, listede komut sat�r�ndan veya grafik ortamdan �al��t�rd���m�z programlar�n d���nda da i�lemler �al�t���n� fark ediyoruz. Bu i�lemlerden baz�lar�n�n isimleri de biraz garip. Sistemizde �al��an i�lemler ve say�lar�, sisteminizin yap�land�r�lmas�na ba�l�d�r. Ancak, baz� ortak i�lemler de vard�r. Sistemde yapt���n�z ayarlar ne olursa olsun, i�lem numaras� 1 ve t�m i�lemlerin babas� olan i�lemin ad� hep "init" tir. ��lem numaras�n�n 1 olmas�, bu program�n i�letim sistemi taraf�ndan hep ilk s�rada �al��t�r�lmas�ndand�r. Fark edece�imiz ba�ka bir konu da, baz� isimlerin sonlar�n�n hep "d" karakteri olmas�d�r. Bunlara verilen genel isim "daemons" dur ve sistemin en �nemli i�lemlerindendirler. init ve daemon lar� daha sonraki bir yaz�da ayr�nt�l� olarak ele alaca��z.
��lem kavram�n� ve onun i�letim sistemimiz i�in olan �nemini kavrad���m�za g�re, daha ileriye giderek �oklui�lem yapan programlar yazmaya ba�layaca��z. A��kar olan ayn� anda birden fazla i�lemin birden �al��t�r�lmas�ndan, daha yeni bir problem olan, i�lemler aras� haberle�me ve zamanlamas�na (senkronizasyon) ge�ece�iz. Bu problemi iki g�zel y�ntem olan mesajlar (messages) ve saya�lar (semaphors) ile ��zece�iz. Bunlar s�re�ler (threads) konusunu i�leyece�imiz sonraki bir yaz�da ayr�nt�l� olarak anlat�lacakt�r. Daha sonra da, t�m anlat�lan y�ntemleri kullanarak, kendi uygulamalar�m�z� yazma zaman� gelecektir.
Standart C k�t�phanesi (Linux,taki libc, glibc taraf�ndan uyarlanm��t�r.) Unix System V'in �oklui�lem y�ntemlerini kullanmaktad�r. Unix System V (Bundan sonra SysV diyece�iz.) ticari bir Unix uyarlamas� olup, BSD Unix ailesi gibi SysV Unix ailesinin de yarat�c�s�d�r.
libc'de i�lem numaras�n�n de�erini tutmak �zere, tamsay� (integer) �eklinde, pid_t de�i�ken tipi tan�mlanm��t�r. Bunadan b�yle, pid_t de�i�ken tipini i�lem numaralar� i�in kullanaca��z. S�rf daha basit olmas� a��s�ndan tamsay� de�i�ken tipini kullanmak da m�mk�nd�r.
Program�m�z�n i�lem numaras�n� elde etmeye yarayan fonksiyona bir g�zatal�m.
pid_t getpid (void)
Bu fonksiyon, pid_tile birlikte unistd.h ve sys/types.h ba�l�k dosyalar�nda tan�mlanm��t�r. �imdi, amac� kendi i�lem numaras�n� bildiren bir program yazal�m. Tercih etti�iniz bir kelime i�lemcisi yard�m� ile a�a��daki program� yaz�n�z.
#include <unistd.h> #include <sys/types.h> #include <stdio.h> int main() { pid_t pid; pid = getpid(); printf("The pid assigned to the process is %d\n", pid); return 0; }Program� print_pid.c ad�nda kaydedin ve a�a��daki komutla derleyin:
gcc -Wall -o print_pid print_pid.cDerleme sonucunda, print_pid adl� �al��t�r�labilir bir program elde etmi� olacaks�n�z. E�er, bulundu�unuz dizin yoltan�m�nda yoksa, program� ancak "./print_pid" olarak �al��t�rabilirsiniz. Program� �al��t�rd���n�zda �ok b�y�k bir s�rpriz ile kar��la�mayacaks�n�z: Ekrana pozitif bir say� g�r�ntileyecektir ve e�er birden fazla �al��t�r�l�rsa da, say�lar hep birbirinden farkl� ve birer birer artan say�lar olacakt�r. Ard���k say�lar elde edilmesi herzaman m�mk�n olmayabilir. Bu zaten olmas� gereken bir durum da de�il. ��nk�, print_pid program�n�n ard���k �al��t�r�lmas� aras�nda ba�ka i�lemler sistem taraf�ndan �al��t�r�lm�� olabilir. Ard���k �al��t�rma aras�nda s�zgelimi, ps komutunu �a�t�r�n.
�imdi bir i�lemin nas�l yarat�laca��n� ��renme zaman� geldi. Ancak, daha �nce, bu i�lem s�ras�nda ger�ekte neler oldu�unu a��klamak gerek. Bir A i�lemi i�erisinden B i�lemi yarat�ld���nda, iki i�lem benzerdir, yani ikisi de ayn� koda sahip, bellek alan� ayn� veriler ile dolu (Bellek alan� ayn� de�il.) ve ayn� i�lemci durumuna sahiptir. Bu a�amadan sonra i�lemler iki farkl� �ekilde devam edebilir: Kullan�c�n�n verece�i giri� bilgisine veya rastgele olan bir veriye g�re. A i�lemine baba "father", B i�lemine de o�ul (son) ad� verilmektedir. init i�leminin t�m i�lemlerin babas� deyimi �imdi daha iyi anla��l�yor olmas� gerekir. Yeni i�lem yaratan fonksiyonun ad�:
pid_t fork(void)d�r. Fonksiyonun d�n�� de�eri i�lem numaras�d�r. Daha �nce de s�yledi�imiz gibi, i�lem kendisini baba ve o�ul olarak, daha sonralar� farkl� i�ler yerine getirmek i�in, ikiye ay�rmaktad�r (kopyalamaktad�r). Ancak, bu i�lemden hemen sonra, hangisi �nce �al��acakt�r? Baba m�, o�ul mu? Cevap �ok basit: �kisinden biri. Hangi i�lemin �al��t�r�lmas� gerekti�i i�letim sistemin zamanlay�c�(scheduler) ad� verilen bir k�sm� taraf�ndan denetlenmektedir ve bu k�s�m, i�lemin baba m�, o�ul mu olup olmad���na bakmaks�z�n, ba�ka parametreleri g�ze alarak belli bir algoritmaya g�re karar vermektedir.
Herneyse, ancak hangi i�lemin hangisi oldu�unu bilmek �nemlidir, ��nk� program�n kodu ayn�d�r. Her iki i�lem de hem baba i�lemin hem de o�ul i�lemin kodunu i�erecektir. �nemli olan herbirinin kendine d��en pay� �al��t�rmalar�d�r. Konuyu daha anla��l�r yapmak i�in, programlama �tesi bir dil gibi g�z�ken a�a��daki algoritmaya bir g�zatal�m:
- FORK - E�ER O�UL �SEN BUNU �ALI�TIR (...) - E�ER BABA �SEN BUNU �ALI�TIR (...)fork fonksiyonu d�n�� de�eri olarak, o�ul i�leme '0' i�lem numaras�n�, baba i�leme de o�ul i�lemin i�lem numaras�n� �retmektedir. Dolay�s�yla d�n�� de�erine bakarak hangi i�lemde oldu�umuzu ��renmemiz m�mk�nd�r. C programlama dilindeki kar��l��� a�a��daki gibi olacakt�r.
int main() { pid_t pid; pid = fork(); if (pid == 0) { O�UL ��LEM�N KODU } BABA ��LEM�N KODU }�oklui�lem olarak �al��an ger�ek bir program yazma zaman� geldi art�k. A�a��daki, program� fork_demo.c dosyas� olarak kay�t edip, yukar�daki komutlara benzer �ekilde derleyebilirsiniz. Program kendi kopyas�n� yaratacak ve hem baba ve hem de o�ul i�lemler bir�ey yazacakt�r. Her�ey yolunda giderse, elde edece�iniz ��kt� ikisinin bir kar���m� olacakt�r.
(01) #include <unistd.h> (02) #include <sys/types.h> (03) #include <stdio.h> (04) int main() (05) { (05) pid_t pid; (06) int i; (07) pid = fork(); (08) if (pid == 0){ (09) for (i = 0; i < 8; i++){ (10) printf("-SON-\n"); (11) } (12) return(0); (13) } (14) for (i = 0; i < 8; i++){ (15) printf("+FATHER+\n"); (16) } (17) return(0); (18) }
(01)-(03) sat�rlar� gerekli ba�l�k k�t�phaneleri (standart Giri�/��k�s I/O,
�oklui�lem) programa dahil etmektedir.
GNU ortamlar�nda oldu�u gibi, main program� bir tamsay�y�,
program hatas�z bir �ekilde sona erdi�inde s�f�r, hatal� olarak sona erirse
hata numaras�n�, d�n�� de�eri olarak �retmektedir.
�u an i�in her�eyin hatas�z sonu�lanaca��n� varsayal�m. Temel kavramlar
anla��ld�k�a programa, hata denetimleri de ekleyece�iz.
(05) sat�r�nda, i�lem numaras�n� tutacak de�i�keni tan�ml�yoruz.
(06) sat�rda, d�ng�lerde kullanaca��m�z bir tamsay� de�i�keni tan�ml�yoruz.
Daha �ncede a��kland��� gibi tamsay� ve pid_t tipleri e�de�erdir. Biz
burada s�rf daha anla��l�r olsun diye b�yle kullan�yoruz.
(07) sat�r�nda, o�ul i�lemine s�f�r ve baba i�lemine o�ul i�lemin
i�lem numaras�n� geri g�nderecek olan fork fonksiyonunu �a��r�yoruz.
Hangisinin hangisi oldu�u denetim sat�r� (08) dir.
(09)-(13) sat�rlar� o�ul, geriye kalan (14)-(16) sat�rlar� da
baba i�leminde �al��t�r�lacakt�r.
Hangi i�lemin �al��t���na ba�l� olarak, k�s�mlar�n yapt��� tek
�ey 8'er defa ekrana "-SON-" veya "+FATHER+" yaz�p 0 de�eri ile
program� bitirmektedir. Bu �ok �nemlidir, ��nk� "return" olmadan,
o�ul i�leminin komutlar�n� yerine getrdikten sonra program�n ak���
gere�i baba i�lemlerine ge�erek devam edebilir. �sterseniz bir deneyin.
Bilgisayar�n�za zarar vermeyecektir, ancak istedi�imizi de tama olarak
yerine getirmemi� olacakt�r. Bu �ekildeki hatalar�n ay�klanmas�
zor olmaktad�r, ��nk� �zellikle karma��k �oklui�lem programlar�n
�al��t�r�lmas� sonucunda farkl� sonu�lar elde edilecek
ve b�ylece hata ay�klanmas� imkans�zla�acakt�r.
Program� �al��t�rd���n�zda belkide sonu�tan memnun kalmayacaks�n�z. Nedenine gelince, elde edilen sonu�lar�n "+FATHER+" ve "-SON-" bir kar���m�ndan ziyade, �nce "+FATHER+" sat�rlar�n�n ard�ndan "-SON-" gelecek veya tam tersi de olabilir. Ancak, program� birden fazla defa �al��t�r�n, belki o zaman sonu� de�i�ebilir.
Herbir printf'ten �nce rastgele bekleme s�resi eklersek, daha fazla �oklui�lem hissi elde etmi� oluruz. Bunu yapabilmek i�in sleep ve rand fonksiyonlar�n� kullan�yoruz.
sleep(rand()%4)Bu komut sayesinde program, 0 ile 3 aras�nda (% tamsay� b�lmede kalan k�sm�n� �retmektedir.) rastgele bir say� kadar bekleme yapacakt�r. �imdi program a�a��daki gibi de�i�mi�tir:
(09) for (i = 0; i < 8; i++){ (->) sleep (rand()%4); (10) printf("-FIGLIO-\n"); (11) }Ayn� �eyi baba i�lemin program par�as� i�in de yapmak gerek. De�i�tirilen program� fork_demo2.c ad� alt�nda saklay�n ve derledikten sonra bir �al��t�r�n. �imdi daha yava� �al��maktad�r, ancak ��kt�daki s�ra farkl�l���n� daha iyi g�rme f�rsat�m�z oldu:
[leo@mobile ipc2]$ ./fork_demo2 -SON- +FATHER+ +FATHER+ -SON- -SON- +FATHER+ +FATHER+ -SON- -FIGLIO- +FATHER+ +FATHER+ -SON- -SON- -SON- +FATHER+ +FATHER+ [leo@mobile ipc2]$
�imdi kar��m�za ��kacak problemlere bir g�z gezdirelim: �oklui�lem ortam�nda baba i�leminden farkl� i�ler yapabilecek birden fazla o�ul i�lemi yaratmam�z olas�d�r. Do�ru zamanda do�ru i�i yapabilmek i�in, baba il�lem, o�ul i�lemler ile haberle�mek zorundad�r. En az�ndan bir zaman ayarlanmas� (synchronize) yap�lmas� gerekmektedir. B�yle bir zaman ayarlanmas�n� olas� k�lan ilk y�ntem wait fonksiyonunu kullanmakt�r.
pid_t waitpid (pid_t PID, int *STATUS_PTR, int OPTIONS)Buradaki PID, sonu�lanmas�n� bekledi�imiz i�lemin i�lem numaras�, STATUS_PTR o�ul i�lemin sonucunun sakland��� tamsay� tipinde bir i�aret�i (E�er, bilgi gerekmiyorsa, bu i�aret�inin de�eri NULL olmaktad�r.) ve OPTIONS �e�itli se�eneklerin se�ilebilece�i bir de�eri, ancak biz �imdilik onunla ilgilenmiyoruz, g�stermektedir. Bu, baba i�lemin o�ul i�lemin sona ermesini bekledi�i ve daha sonra program� sona erdirdi�i bir �rnektir.
#include <unistd.h> #include <sys/types.h> #include <stdio.h> int main() { pid_t pid; int i; pid = fork(); if (pid == 0){ for (i = 0; i < 14; i++){ sleep (rand()%4); printf("-SON-\n"); } return 0; } sleep (rand()%4); printf("+FATHER+ Waiting for son's termination...\n"); waitpid (pid, NULL, 0); printf("+FATHER+ ...ended\n"); return 0; }Baba i�leminin k�sm�na sleep fonksiyonu, farkl� �al��t�rma durumlar�n� ortaya koymak i�in eklenmi�tir. Program� fork_demo3.c olarak kay�t edelim ve derledikten sonra da �al��t�ral�m. ��te �imdi zaman ayarlamas� yap�lm�� ilk program�m�z� yazm�� olduk!
Bir sonraki yaz�da zamanlama ayarlamas� ve i�lemler aras� ileti�im konusu hakk�nda daha fazla bilgi edinece�iz. �u ana kadar anlat�lan fonksiyonlar� kullanarak kendi programlar�n�z� yaz�n ve a��klamalar� ile birlikte .c dosyas� halinde bana g�nderin. B�ylece ben aralar�ndan iyi olan ��z�mler ile k�t�leri g�sterme �ans� elde etmi� olurum. Ad�n�z� ve e-posta adresinizi yazmay� unutma�n. �yi �al��malar!
|
G�rsely�re sayfalar�n�n bak�m�, LinuxFocus Edit�rleri taraf�ndan yap�lmaktad�r
© Leonardo Giordani, FDL LinuxFocus.org |
�eviri bilgisi:
|
2002-11-28, generated by lfparser version 2.31