[LinuxFocus-icon]
Ev  |  Eri�imd�zeni  |  ��indekiler  |  Arama

Duyumlar | Belgelikler | Ba�lant�lar | LF Nedir
Bu makalenin farkl� dillerde bulundu�u adresler: English  Castellano  Deutsch  Francais  Italiano  Nederlands  Russian  Turkce  Polish  

convert to palmConvert to GutenPalm
or to PalmDoc

[Photo of the Author]
taraf�ndan Leo Giordani
<leo.giordani(at)libero.it>

Yazar hakk�nda:
Milan,Politecnico'da Telekominikasyon Fak�ltesi'nde ��renci.Netwok y�neticili�i yap�yor ve programlama ( �zellikle assembly ve C++) ile ilgileniyor.1999'dan beri �zellikle Linux/Unix �zerinde �al���yor.

T�rk�e'ye �eviri:
�zcan G�ng�r <ozcangungor(at)netscape.net>

��erik:

 

Title: E�zamanl� Programlama - ��lemler aras� ileti�im

[Illustration]

�zet:

Bu makale dizisinin amac�, okuyucuya �oklui�lemler ve onun Linux'ta uygulan��� hakk�nda bilgi vermektir.Teorik bilgilerden ba�lay�p i�lemler aras� ileti�im �rne�i g�steren tamamlanm�� bir �rnek verece�iz.Basit ama etkili bir ileti�im protok� kullanaca��z.
Makalenin anla��labilmesi i�in �u bilgilere gereksinim vard�r:

  • Biraz kabuk bilgisi
  • Temel C bilgisi ( yaz�m, d�ng�ler, k�t�phaneler )
�ncelikle Kas�m 2002,makale 272 'yi okumal�s�n�z ��nk� bu makalenin devam�d�r.
_________________ _________________ _________________

 

Giri�

Burada Linux'ta �oklui�lemleri a��klayaca��z.Bir �nceki makalede g�rd���m�z gibi bir program�n �al��mas�n� b�lmek i�in bir ka� kod sat�r� yeterlidir.��nk� i�letim sistemi yaratt���m�z i�lemlerin ba�lang���, y�netilmesi ve zamanlamas�yla ilgilenir.
��letim sistemi taraf�ndan sa�lanan servis biricil �neme sahiptir, o i�lemlerin "�al��ma y�neticisi"dir.Yani i�lemler belirli bir ortamda �al���t�r�l�r.��lemler �al���rken  kontrol�n�n kayb�, programc�ya e�zamanl�l�k sorunu getirir.�lgilendi�imiz soru �udur:�ki ba��ms�z i�lemi nas�l bir arada �al��tabiliriz?
Sorun sand���m�zdan daha kar���kt�r:Sorun sadece iki i�lemin e�zamanlamas� de�il. Veri payla��m� ve okuma-yazma da sorundur.
S�radan bir e�zamanlama sorusu d���nelim:E�er iki i�lem ayn� anda bir veri k�mesini okuyacaksa sorun yoktur.�al��ma bi�imlerinde de�i�iklik olmaz ve hep ayn� sonucu �retirler.�imdi i�lemlerden birinin veri k�mesini de�i�tirmek istedi�ini d���nelim.�kinci i�lemin ilk i�lemden �nce ya da sonra �al��mas�na g�re verece�i sonu� farkl� olacakt�r.�ren�in:"A" ve "B" iki i�lemimiz ve "d" bir tam say� olsun.A i�lemi d'yi 1 art�r�r.B ise d'yi ekrana yazd�r�r.Bunu �u �ekilde ifade edebiliriz:

A { d->d+1 } & B { d->output }

Burada "&" e�zamanal� i�lemi ifade eder.Birinci m�mk�n �al��ma:

(-) d = 5 (A) d = 6 (B) output = 6

ama e�er �nce B �al���rsa �unu elde ederiz :

(-) d = 5 (B) output = 5 (A) d = 6

Bu �rnekten e�zamanal� �al��man�n do�ru y�netilmesinin �nemini anl�yorsunuz.Verilerin ayn� olmamas� riski b�y�kt�r ve kabul edilemez.Bu veri k�melerinin banka hesaplar�n�z oldu�unu d���n�n.Bu sorunu asla k���msemezsiniz.
Bir �nceki makalede waitpid(2) fonksiyonu kullanarak e�zamanlaman�n ilk bi�imini g�rm��t�rk.Bu fonksiyon, bir i�lemin devam etmeden �nce ba�ka bir i�lemin bitmesi i�in  beklemeye yarar.Asl�nda bu, okuma-yazma an�nda olu�abilecek karma��kl��� b�y�k �l��de engeller.Bir veri k�mesi �zerinde P1 �al���yorsa, P2 ayn� veri k�mesinde veya bir alt k�mesinde �al��acaksa �nce P1'in bitmesini beklemek zorundad�r.
A��kca bu y�ntem bir ��z�md�r.fakan en iyisi de�ildir.P2, P1'in i�leminin bitmesi i�in -�ok k�sa s�recekse bile- uzun zaman bekleyecektir.Biz kontrol�m�z�n alan�n� daraltmal�y�z.�rne�in:tek bir veriye ya da  veri k�mesine eri�me gibi.Bu sorunun ��z�m� k�t�phanelerin temeli olan,SysV IPC(System V InterProcess Communication-SistemV ��lemleraras� �leti�im) ad� verilen bir tak�m k�t�phane ile verilir.  

SysV Anahtarlar�

E�zamanl�l�k ve onun uygulamal�r� ile ilgili teorilere girmeden �nce tipik SysV yap�s�na bir g�z atal�m:IPC anahtarlar�.Bir IPC anahtar�, bir IPC kontrol yap�s�n� (daha sonra a��klanacakt�r) belirleyen bir say�d�r.Ancak bu, ayn� tip belirleyicileri �retmek i�in de kullan�l�r.�rene�in: no-IPC yap�lar�n� organize etmek i�in.Bir anahtar ftok(3) fonksiyonu kullan�larak olu�turulur:

key_t ftok(const char *pathname, int proj_id);

Bu fonksiyon, var olan bir dosya ad�n� (pathname) ve bir tam say� kullan�r.Anahtar�n tek olaca��n�n garantisi yoktur ��nk� dosyadan al�nan parametreler (i-node say�s� ve s�r�c� numaras�), benzer kombinasyonlar�  olu�turabilir.Var olan anahtarlar� kontrol eden ve ayn� anahtar�n kullan�mas�n� engelleyecek k���k bir k�t�phane olu�turmak iyi bir ��z�m olacakt�r.
   

Semaforlar

Ara� trafi�inde kullan�lan semaforlar hi� de�i�tirilmeden veri ak��� kontrol�nde de kullan�labilir.Bir semafor, s�f�r vaya daha b�y�k bir de�er alan ve semafordaki bir ko�ulun ger�ekle�mesini bekleyen i�lem kuyru�unu y�neten bir yap�d�r.Semaforlar�n basit gibi g�r�nmelerine kar��n �ok g��l�d�rler.Hata kontrol�n� d��ar�da b�rakarak ba�layal�m:Semaforlar� kama��k programlarla kar��la�t���m�zda kullanaca��z.
Semaforlar kontrol kaynaklar�na ula��rken kullan�labilirler:Semaforun de�eri, bir kayna�a ula�maya �al��an bir i�lemin numaras�n� g�sterir.Bir i�lem bir kayna�a her ula�maya �al��t��� zaman semafonun de�eri azalt�l�r ve i�lemin kaynakla i�i bitti�inde tekrar art�l�r.E�er kaynak �zel ise ( sadce bir i�lem ula�abiliyorsa ) semaforun ba�lang�� de�eri 1 olur.
Semafora benzer farkl� bir kavram daha vard�r: kaynak sayac�.Bu de�er, bu durumda, ula��labilir kaynak say�s�n� g�sterir ( serbest bellek h�cre say�s� gibi ).
Ger�ek bir durum d���nelim.Semafor tipleri kullan�ls�n:S1,..,Sn i�lemlerinin yazma hakk� olan ama sadece L i�leminin okuma hakk� olan bir tampon var.Bu tampon �zerinde belirli bir anda sadece bir i�lem �al��abilsin.S i�lemlerinin tamponun dolmas� d���nda her zaman tampona yazabiliriler ve L i�lemi sadece tampon bo� olmad��� zaman okuyabilir.Bu durumda �� semafora gereksini var:Birincisi kayna�a eri�imi y�netir, ikinci ve ���nc� semafor tampondaki eleman say�s�n� tutar (ileride neden iki semaforun yeterli olmad���n� g�rece�iz).
Tamponun �zel oldu�unu d���nelim.Birinci semafor sadece 0 veya 1 de�erini alabilir.�kinci ve ���nc� semaforun alabilece�i de�er tamponun boyutuna ba�l�d�r.
�imdi semaforlar�n C'de SysV'yi kullanarak nas�l uyguland���n� g�relim.Semaforlar� olu�turan fonksiyon semget(2)'dir:

int semget(key_t key, int nsems, int semflg);

Burada key,IPC anahtar�d�r.nsems, olu�turmak istedi�imiz semafor say�s�d�r.semflg, 12 bitlik eri�im kontorl�d�r.�lk 3'� olu�turma politikas�na g�re de�i�ir, di�er 9'� ise kullan�c�, group ve di�erlerinin (Unix dosya sistemindeki gibi) okuma ve yazma haklar�d�r.Tam a��klama i�in ipc(5)'nin kullanma klavuzunu okuyun.Farketti�iniz gibi SysV bir semafor k�mesini kontrol eder ve bu sebeple kod daha k���kt�r.
�lk semaforumuzu olu�tural�m:

#include <stdio.h>
#include <stdlib.h>
#include <linux/types.h>
#include <linux/ipc.h>
#include <linux/sem.h>
int main(void)
{
  key_t key;
  int semid;
  key = ftok("/etc/fstab", getpid());
  /* Bir semafor i�ren bir semafor k�mesi olu�tural�m */
  semid = semget(key, 1, 0666 | IPC_CREAT);
  return 0;
}

�leride semaforlar�n nas�l y�netildi�ini ve silindi�ini ��renece�iz.Semaforu y�netme fonksiyonu semctl(2)'dir:

int semctl(int semid, int semnum, int cmd, ...)

Burada parametreler semafor k�mesinin veya (istenirse) sadece semnum ile belirtilen semaforun i�levine ba�l� olarak cmd ile verilir.Biz gereksinim duyduk�a baz� se�enekleri anlataca��z.Ama t�m liste kullanma klavuzunda verilmi�tir.cmd i�levine ba�l� olarak fonksiyon i�in ba�ka parametreler de tam�nlamak gerekebilir.�u �ekildedir:

union semun {
 int val;                  /* SETVAL de�eri */
 struct semid_ds *buf;     /* IPC_STAT, IPC_SET i�in tampon*/
 unsigned short *array;    /* GETALL, SETALL i�in dizi*/
                           /* Linux'a �zg� k�s�m */
 struct seminfo *__buf;    /* IPC_INFO i�in tampon*/
};

Semafora de�er verebilmek i�in SETVAL y�nergesi kullan�mla�d�r ve bu de�er semun birli�inde (union) belirtilmelidir:Bir �nceki programdaki semforun de�erini 1 yapal�m:

[...]
  /* Bir semaforlu bir semafor k�mesi olu�tur */
  semid = semget(key, 1, 0666 | IPC_CREAT);
  /* 0 numaral� semaforun de�erini 1 yap */
  arg.val = 1;
  semctl(semid, 0, SETVAL, arg);
[...]

�imdi semafor i�in ayr�lm�� yeri bo�altmam�z gerekiyor.Bu i�lem, semctl fonksiyonunda IPC_RMID y�nergesi ile yap�l�r.Bu i�lem semaforu siler ve bu kayna�a ula�mak i�in bekleyen  but�n i�lemlere bir ileti g�nderir.Yukar�daki program�n devam� olarak:

[...]
  /* Semafore 0'in de�erini 1 yap */
  arg.val = 1;
  semctl(semid, 0, SETVAL, arg);
  /* Semaforu sil */
  semctl(semid, 0, IPC_RMID);
[...]

Daha �nce de g�rd���m�z gibi e�zamanl� i�lerleri oluturmak ve y�netmek zor de�ildir.Hata y�netimi i�in i�ine girdi�inde, kodun karma��kl�l��� a��s�ndan i�ler biraz zorla�acak.
Art�k semafor semop(2) fonksiyonu ile kullan�labilir:

int semop(int semid, struct sembuf *sops, unsigned nsops);

Burada semid, k�menin belirteci; sops, yap�lacak i�lemler dizisi ve nsops bu i�lemlerin say�s�d�r.B�t�n i�lemler sembuf yap�s�yla temsil edilir:

unsigned short sem_num; short sem_op; short sem_flg;

�rne�in k�medeki semaforun numaras� (sem_num), i�lem (sem_op) ve bekleme politikas�n� ayarlayan bayrak (�imdilik sem_flg 0 olsun).Belirleyece�imiz i�lemler tam say�lard�r ve a�a��daki kurallara uyar:
 

  1. sem_op < 0

  2. E�er semaforun mutlak de�eri sem_op' e�it veya sem_op'dan b�y�kse, i�lem devam eder ve semaforun de�erine sem_op eklenir.E�er semaforun mutlak de�eri sem_op'dan k���kse, i�lem belirli bir kaynak numar�s� ula��labilir olana kadar uyku durumuna ge�er.
  3. sem_op=0

  4. ��lem, semaforun de�eri 0 oluncaya kadar uyku durumuna ge�er.
  5. sem _op > 0

  6. sem_op de�eri, semaforun de�erine eklenir ve daha �nce kullan�lan kaynak b�rak�l�r.
A�a��daki program, semaforlar�n nas�l kullan�laca��n� g�teriri.Ayr�ca daha �nce verdi�imiz tampon �rne�inin kulan�m�n� da g�sterir:Biz be� adet Y (yazma) ve bir adet O (okuma) i�lemi ou�turaca��z.Her Y i�lemi semafor kullanarak eri�ece�i kayna�� (tampon) kilitleyecek.E�er tampon dolu de�ilse, tampona bie eleman koyacak ve tamponu b�rakacakt�r.O i�lemi, tamponu kilitler, tampon bo� de�ilse bir eleman al�r ve kilidi kald�r�r.
Neden �� semafora gereksinimimiz var?�lki (0 numaral� semafor), tamponun eri�im kilididir ve en b�y�k de�eri 1'dir.Di�er iki semafor dolulu�u ve bo�lu�u temsil eder.
Durumu daha a��k anlatal�m: bir semaforumuz (ad� O olsun) olsun ve tampondaki bo� yerin de�erini tutsun.Bir S i�lemi her tambona bir�ey koydu�unda bu de�er 1 azal�r.Ve bu s�f�r de�eri al�ncaya kadar devam eder yani tampon dolana kadar.Bu semafor bo�lu�u temsil edemez: R i�lemi kendi de�erini s�n�rs�z art�rabilir.Bundan dolay� ba�ka bir semafora (ad� U olsun) gereksinim duyar�z.Bu semafor tampondaki eleman say�s�n� tutar.W i�lemi her tampona bir eleman koydu�unda, W'nun de�erini art�r�r ve O'nun de�erini azalt�r.Tersi durumda, R i�lemi, U'nun de�erini azalt�r ve O'nun de�erini art�r�r.

Doluluk, O semaforunun de�erini artamamak ile; bo�luk, U semaforunu de�erini azaltamamak ile anla��l�r.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <linux/types.h>
#include <linux/ipc.h>
#include <linux/sem.h>
int main(int argc, char *argv[])
{
  /* IPC */
  pid_t pid;
  key_t key;
  int semid;
  union semun arg;
  struct sembuf lock_res = {0, -1, 0};
  struct sembuf rel_res = {0, 1, 0};
  struct sembuf push[2] = {1, -1, IPC_NOWAIT, 2, 1, IPC_NOWAIT};
  struct sembuf pop[2] = {1, 1, IPC_NOWAIT, 2, -1, IPC_NOWAIT};
  /* Di�erleri */
  int i;
  if(argc < 2){
    printf("Kullan�m: bufdemo [b�oyut]\n");
    exit(0);
  }
  /* Semaforlar */
  key = ftok("/etc/fstab", getpid());
  /* 3 semafor i�eren semafor k�mesi olu�tur */
  semid = semget(key, 3, 0666 | IPC_CREAT);
  /* Semaphore #0'�n de�erini  1 yap - Kaynak kontrol� */
  arg.val = 1;
  semctl(semid, 0, SETVAL, arg);
  /* Semafor #1'in de�erini buf_length yap- Doluluk kontrol� */
  /* Sem'in de�eri 'tampondaki bo� yer'dir */
  arg.val = atol(argv[1]);
  semctl(semid, 1, SETVAL, arg);
  /* Semafor #2'nin de�eri buf_length'dir - Bo�luk kontrol� */
  /* Sem'in de�eri 'tampondaki eleman say�s'd�r */
  arg.val = 0;
  semctl(semid, 2, SETVAL, arg);
  /* Ay�rma */
  for (i = 0; i < 5; i++){
    pid = fork();
    if (!pid){
      for (i = 0; i < 20; i++){
 sleep(rand()%6);
 /* Kayna�� kilitlemeyi dene - sem #0 */
 if (semop(semid, &lock_res, 1) == -1){
   perror("semop:lock_res");
 }
 /* Bir serbest bo�lu�u kilitle - sem #1 / Bir eleman koy - sem #2*/
 if (semop(semid, &push, 2) != -1){
   printf("---> ��lem:%d\n", getpid());
 }
 else{
   printf("---> ��lem:%d  TAMPON DOLU\n", getpid());
 }
 /* Kayna�� b�rak */
 semop(semid, &rel_res, 1);
      }
      exit(0);
    }
  }
  for (i = 0;i < 100; i++){
    sleep(rand()%3);
    /* Kayna�� kilitlemeyi dene - sem #0 */
    if (semop(semid, &lock_res, 1) == -1){
      perror("semop:lock_res");
    }
    /* Serbest bo�lu�un kilidini kald�r - sem #1 / Bir eleman al - sem #2 */
    if (semop(semid, &pop, 2) != -1){
      printf("<--- ��lem:%d\n", getpid());
    }
    else printf("<--- ��lem:%d  TAMPON BO�\n", getpid());
    /* Kayna�� b�rak */
    semop(semid, &rel_res, 1);
  }
  /* Seamforlar� sil */
  semctl(semid, 0, IPC_RMID);
  return 0;
}

Koddaki �u ilgin� sat�lara bakal�m:

struct sembuf lock_res = {0, -1, 0};
struct sembuf rel_res = {0, 1, 0};
struct sembuf push[2] = {1, -1, IPC_NOWAIT, 2, 1, IPC_NOWAIT};
struct sembuf pop[2] = {1, 1, IPC_NOWAIT, 2, -1, IPC_NOWAIT};

Bu d�rt sat�r, semaforlar �zerinde yapabilece�imiz i�lemlerdir: �lk ikisi tek i�lem iken di�er iki i�lem �ift i�lemdir.�lk i�lem, lock_res, kayna�� kilitmeyi dener:Bu i�lem ilk semaforun (0 numaral�) de�erini -e�er semaforun de�eri s�f�r de�ilse- bir azalt�r.Kayna��n kilitli olmas� durunda politika hi�biri de�ildir (�rne�in ilem bekleme durumunda).rel_res, lock_res'e benzer ama kaynak b�rak�l�r( de�eri pozitiftir) .
Ekleme ve ��karma i�lemleri biraz �zeldir.Bunlar iki i�lem dizisidir.Birincisi 1 numaral� semafor �zerinde ve ikincisi 2 numaral� semafor �zerindedir.Birincisi art�rma iken ikincisi azaltmad�r veya tam tersi.Ama politika art�k bekleme durumu de�ildir:IPC_NOWAIT, i�lemi, kaynak kilitli ise �al��mas�na devam etmesi i�in zorlar.

/* Semafo #0'in de�erini 1 yap - Kaynak kontrol� */
arg.val = 1;
semctl(semid, 0, SETVAL, arg);
/* Semafor #1'i  buf_length yap - Doluluk kontrol� */
/* Sem'in de�eri  'tampondaki bo� yer'dir */
arg.val = atol(argv[1]);
semctl(semid, 1, SETVAL, arg);
/* Semafor #2'yi buf_length yap - Bo�luk kontrol� */
/* Sem'in de�eri 'tampondaki eleman say�s�'dir */
arg.val = 0;
semctl(semid, 2, SETVAL, arg);

Burada semaforlara ilk de�erlerini veririz..Birincisini 1 yapar�z ��nk� belirili bir kayna�a ula�may� kontrol eder.�kincisini, tamponun uzunlu�una e�itleriz.���nc�s�n� ise bo�luk ve dolulu�u g�sterir.

/* Kayna�� kilitlemeye �al�� - sem #0 */
if (semop(semid, &lock_res, 1) == -1){
  perror("semop:lock_res");
}
/* Bir bo� yer kilitle - sem #1 / Bir eleman koy - sem #2*/
if (semop(semid, &push, 2) != -1){
  printf("---> ��lem:%d\n", getpid());
}
else{
  printf("---> ��lem:%d  TAMPON DOLU\n", getpid());
}
/* Kaynaktaki kilidi kald�r */
semop(semid, &rel_res, 1);

Y i�lemi, kayna�� lock_res fonksiyonunu kullanarak kilitlemeya �al���r.Bunu ger�ekle�tirdikten sonra kayna�a bir eleman koyar ve bunu ekrana yazar.E�er bu i�lemi yapamazsa ekrana "TAMPON DOLU" iletisini yazar.Daha sonra kayna�� serbest b�rak�r.

/* Kayna�� kilitlemeyi dene - sem #0 */
    if (semop(semid, &lock_res, 1) == -1){
      perror("semop:lock_res");
    }
    /* Serbest bo�lu�un kilidini kald�r - sem #1 / Bir eleman al - sem #2 */
    if (semop(semid, &pop, 2) != -1){
      printf("<--- ��lem:%d\n", getpid());
    }
    else printf("<--- ��lem:%d  TAMPON BO�\n", getpid());
    /* Kayna�� b�rak */
    semop(semid, &rel_res, 1);

O i�lemi, az �ok Y kadar �al��t�r�l�r:Kayna�� kilitler, bir eleman al�r ve kayna�� serbest b�rak�r.

Bir sonraki  makalede, ileti kuyruklar�ndan, ��lemleraras� �leti�imin ve e�zamanlaman�n farkl� bir yap�s�ndan bahsedece�iz.Bu makaleyi kullanarak yazd���n�z programlar� -basit olsalar bile- bana da g�nderin ( isim ve e-posta adreslerinizle birlikte ).Bunlar� okumaktan memnun olaca��m.�yi �al��malar.
   

�nerilen Kaynaklar

 

Bu yaz� i�in g�r�� bildiriminde bulunabilirsiniz

Her yaz� kendi g�r�� bildirim sayfas�na sahiptir. Bu sayfaya yorumlar�n�z� yazabilir ve di�er okuyucular�n yorumlar�na bakabilirsiniz.
 talkback page 

G�rsely�re sayfalar�n�n bak�m�, LinuxFocus Edit�rleri taraf�ndan yap�lmaktad�r
© Leo Giordani, FDL
LinuxFocus.org
�eviri bilgisi:
en --> -- : Leo Giordani <leo.giordani(at)libero.it>
en --> tr: �zcan G�ng�r <ozcangungor(at)netscape.net>

2003-02-03, generated by lfparser version 2.35