|
|
Bu makalenin farkl� dillerde bulundu�u adresler: English Castellano Deutsch Francais Italiano Nederlands Russian Turkce Polish |
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�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.
|
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.
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.
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:
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.
|
G�rsely�re sayfalar�n�n bak�m�, LinuxFocus Edit�rleri taraf�ndan yap�lmaktad�r
© Leo Giordani, FDL LinuxFocus.org |
�eviri bilgisi:
|
2003-02-03, generated by lfparser version 2.35