İnönü Üniversitesi Bilgisayar Mühendisliği Bölümü

Slides:



Advertisements
Benzer bir sunumlar
Algoritma.  Algoritma, belirli bir görevi yerine getiren sonlu sayıdaki işlemler dizisidir.  Başka bir deyişle; bir sorunu çözebilmek için gerekli olan.
Advertisements

Hat Dengeleme.
BULUT BİLİŞİM M. KÜRŞAT YILDIRIM İÇERİK  BULUT BİLİŞİM NEDİR?  BULUT BİLİŞİM ÖZELLİKLERİ  BULUT BİLİŞİM MİMARİ YAPISI  BULUT BİLİŞİM.
YEDEKLEME NEDIR? Gülşen Güler. YEDEKLEME NEDIR? Yedekleme, en genel anlamıyla, bir bilgisayar sistemini işlevsel kılan temel birimlerin, üzerinde çalışan.
BÖLÜM 1 TEMEL KAVRAMLAR. BÖLÜM 1 TEMEL KAVRAMLAR.
SUNUCU İŞLETİM SİSTEMİ Öğr. Gör. Ümit ATİLA.  1980’li yıllardan günümüze geldikçe, bilgi toplumuna yönelişte teknolojik rota, telekomünikasyon ve iletişim.
Tane Kavramının Öğretimi (Basamaklandırılmış Yönteme Göre)
BİLGİSAYAR PROGRAMLAMA Ders 11: İşaretçi (Pointer) Kullanımı Yrd. Doç. Dr. Altan MESUT Trakya Üniversitesi Bilgisayar Mühendisliği.
Zihinsel engellilerin sınıflandırılması
İNSAN BİLGİSAYAR ETKİLEŞİMİ: BİLİŞSEL BOYUT III. İBE alanında etkileşimi anlamaya çalışan uzmanlar, özellikle şema ve zihinsel modeller üzerinde yoğunlaşırlar.
İŞLETİM SİSTEMLERİ ISE 206 DR. TUĞRUL TAŞCI. Dersin Amacı Bilgisayar sistemlerinin temel organizasyonunu tanımak İşletim sistemlerinin ana bileşenlerini.
O R T L G İ M A A Ve Problem çözme.
İÇİNDEKİLER GRID COMPUTING NEDİR? NASIL ÇALIŞIR? GRID COMPUTING YAPISI
Program Tasarım Modelleri
Yazılım Mühendisliği1[ 3.hft ]. Yazılım Mühendisliği2 Yazılım İ sterlerinin Çözümlemesi Yazılım Yaşam Çevrimi “ Yazılım Yaşam çevrimin herhangi bir yazılım.
Doç. Dr. Cemil Öz SAÜ Bilgisayar Mühendisliği Dr. Cemil Öz.
Pazarlama İlkeleri.
BİLGİSAYAR PROGRAMLAMA DERSİ
ENGELSİZ ÜNİVERSİTE FAALİYET RAPORU
Vize Öncesi.
İŞLETİM SİSTEMLERİ ISE 206 Dr. Tuğrul TAŞCI.
PROGRAMLI ÖĞRETİM Tanımı:
Proje Oluşturma ve Yönetimi Bilişim Teknolojileri Öğretmeni
PROGRAMLAMAYA GİRİŞ VE ALGORİTMA
Proje Oluşturma ve Yönetimi
DENEYSEL TERTİPLER VE PAZAR DENEMESİ
Öğretimin Uyarlanması
Problem Çözme ve Algoritmalar
Yapay Sinir Ağı Modeli (öğretmenli öğrenme) Çok Katmanlı Algılayıcı
PROGRAMLAMA TEMELLERİ
MODEL YETERSİZLİKLERİNİ DÜZELTMEK İÇİN DÖNÜŞÜMLER VE AĞIRLIKLANDIRMA
ADANA İL MİLLİ EĞİTİM MÜDÜRLÜĞÜ
PPT 6 Kapsayıcı bir eğitim için nasıl bir sınıf yönetimi yaklaşımı benimsemeliyim? Sınıfında Yabancı Uyruklu Öğrenci Bulunan Milli Eğitim Bakanlığı Öğretmenlerinin.
EKRAN KARTLARI.
KAYNAŞTIRMA EĞİTİMİ.
Uçak Bileti Değiştirme
Program Tasarım Modelleri
STORAGE BÜŞRA KARADENİZ
TUTUM VE ALGILAR.
ZEE ZİHİN ENGELLİLERE BECERİ VE KAVRAM ÖĞRETİMİ
MATEMATİK DERSİ ÖĞRETİM PROGRAMI
Temel Bilgisayar Bilgileri
PROBLEM ÇÖZME VE ALGORİTMALAR
Bilgisayar Mühendisliğine Giriş
3.hafta METODLAR.
Bölüm 7 İfadeler ve atamalar.
B+-Ağaçları.
İşletim Sistemleri (Operating Systems)
İşletim Sistemleri (Operating Systems)
NİŞANTAŞI ÜNİVERSİTESİ
ANALİTİK KİMYA DERS NOTLARI
PROGRAMLAMAYA GİRİŞ VE ALGORİTMA
NİŞANTAŞI ÜNİVERSİTESİ
Bilgisayar Bilimi Koşullu Durumlar.
İŞLETİM SİSTEMİ KATMANLARI (Çekirdek, Kabuk ve diğer temel kavramlar)
NİŞANTAŞI ÜNİVERSİTESİ
Değerler ve Değişkenler
Gelişim ve Temel Kavramlar
İşlemciler.
DİL GELİŞİMİ KURAMLARI - II
NİŞANTAŞI ÜNİVERSİTESİ
Bilgisayar Bilimi Programlama Yapısı.
NİŞANTAŞI ÜNİVERSİTESİ
NİŞANTAŞI ÜNİVERSİTESİ
NİŞANTAŞI ÜNİVERSİTESİ
MTM216 GÖRSEL PROGRAMLAMA
Kesikli Olay benzetimi Bileşenleri
Eğitsel Robotların Bileşenleri-2
İleri Algoritma Analizi
Bilimsel araştırma türleri (Deneysel Desenler)
Sunum transkripti:

İnönü Üniversitesi Bilgisayar Mühendisliği Bölümü İş Senkronizasyonu İnönü Üniversitesi Bilgisayar Mühendisliği Bölümü

Nedir Süreçlerin/ipliklerin faaliyetlerinin paylaşılan veriye erişildiğinde (veri tutarsızlığı vb.) sıkıntı çıkmayacak şekilde koordineli olarak yürütülmesidir. Veri tutarlılığını muhafaza etmek işbirliği yapan süreçlerin düzenli çalıştırılmasını garantileyen mekanizmalar gerektirir.

Kritik Bölümler (Tekrar) X ve Y paylaşılan veriler olsun. İplik 1 Kodu İplik 2 Kodu İplik 3 Kodu X’i Değiştir X’i Değiştir Y’i Değiştir Y’i Değiştir Y’i Değiştir X’i Değiştir

Karşılıklı Dışlama (Mutual Exclusion - Mutex) 2 sürecin veya ipliğin kritik bölgede aynı anda olmasına müsaade etmemektedir. Süreçlerin/ipliklerin çalışmalarının rastgele aralıklarla ve oranlarla yapıldığını (preemptive scheduling) varsaymak zorundadır. Zamanlama uygulamanın kontrolünde değildir. Veri senkronizasyonuyla koordinasyon sağlanır. Tutarlılığı sağlamak için talimatların dönüşümlü çalışması sınırlanır. Düşük seviyeli ve yüksek seviyeli mekanizmalarla sağlanır.

Karşılıklı Dışlama Sorunu: Aç Kalma Bir süreci diğer süreçlerin lehine olacak şekilde sürekli erteleme sorunudur. Belirsiz erteleme olarak da bilinir. Genellikle kötü bir zamanlama algoritması neden olur. Bir tür yaşlandırma tekniği geliştirmek çözüm olabilir. Böyle değil!

Karşılıklı Dışlama Sorunu: Ölümcül Kilitlenme İki yada daha fazla sürecin hiçbir zaman olmayacak bir olayı beklemeye kilitlenmeleridir. Genellikle A süreci B’nin iş yapmasını bekler, B de A’ yı bekler. İkisi de beklemede kalakaldıkları için hiçbir iş yapmazlar ve hiçbir zaman bu süreçlere bağlı olaylar oluşmaz. Ayrıca ele alınacaktır.

Genel Senkronizasyon Yöntemi

Yarış Durumu Örneği Kritik bölüme uyuluyor Uyulmuyor Kritik Bölümler

Üretici Tüketici Yarış Durumu Tamponda 5 nesne olsun. Üreticinin yeni bir nesne üretip tampona koyup miktarı arttırdığı varsayılsın. Tüketicinin de tampondan bir nesne alıp miktarı azalttığı varsayılsın. Üretici Tüketici veya Üretici Tüketici

Üretici Tüketici Yarış Durumu Kritik bölge miktar değerinin değiştirildiği yerdir. Miktar şu şekilde arttırılabilir. (aynı şekilde azaltılabilir) yazmac1 = miktar; //değeri oku yazmac1 += 1; //değeri arttır miktar = yazmac1; //geri yerine yaz

Üretici Tüketici Yarış Durumu O halde Miktar yazmac1 Üretici (miktar++) 5 6 5 4 6 register1 = count register1 = register1 + 1 count = register1 register1 = count register1 = register1 + 1 count = register1 yazmac2 5 4 Tüketici (miktar--) register2 = count register2 = register2 – 1 count = register2 register2 = count register2 = register2 – 1 count = register2 CPU Ana Bellek

Hesap Bakiyesi Yarış Durumu İki müşteriden her biri 100TL çekse de, bakiye 800TL yerine 900TL olur.  Bakiye = 1000TL balance = get_balance(account); balance -= amount; Yerel = 900TL İşlemcinin gördüğü çalıştırma dizisi balance = get_balance(account); balance -= amount; put_balance(account, balance); Yerel = 900TL Bakiye = 900TL put_balance(account, balance);

Karşılıklı Dışlama Gösterimi Kritik Bölge Kritik Bölge İplik 1 İplik 2 İplik 1 (hesap bakiyesini değiştir) (hesap bakiyesini değiştir) Kritik Bölge İplik 2 (hesap bakiyesini değiştir) 2. iplik serbestçe girebilir 1. iplik kritik bölgeden ayrılır.

POSIX ile Karşılıklı Dışlama pthread_mutex_lock(&myMutex) .. //kritik bölge detayları pthread_mutex_unlock(&myMutex)

Kritik Bölge Şartları Karşılıklı Dışlama: En fazla 1 iplik kritik bölge içinde çalışabilir. İlerleme: Eğer T1 ipliği kritik bölge dışındaysa, T1 ipliği T2 ipliğinin kritik bölgeye girmesine engel olmamalıdır. Aç kalmama: Eğer T1 ipliği kritik bölgeye girmeyi bekliyorsa, eninde sonunda girecektir. İpliklerin kritik bölgeden eninde sonunda çıkacağı kabul edilir. Performans: Kritik bölgeye girme/bölgeden çıkmanın iş yükü bölgede yapılan işe göre küçük olmalıdır.

Kilitler Aşağıdaki iki işlem yapan (bellekteki) nesnelerdir. lock(): Bir iplik kritik bölgeye girmeden önce bunu çağırır, giriş için beklemeyi gerektirebilir. unlock(): Bir iplik kritik bölgeden çıktıktan sonra bunu çağırır, başka bir ipliğin kritik bölgeye girmesini sağlar. Bir lock() çağrısının mutlaka bir unlock() karşılığı olmalıdır. İplik bu iki çağrı arasında kilidi muhafaza eder. Çağıran kilidi tutana kadar lock() dönüş yapmaz. Bir anda en fazla bir iplik bir kilit tutabilir. (istisnalar mevcuttur.)

Kilitler int withdraw(account, amount) { lock(kilitdegiskeni); balance = get_balance(account); balance -= amount; put_balance(account, balance); unlock(kilitdegiskeni); return balance; } Kritik bölge

Dönen Kilitler (Spinlocks) Oldukça basit bir kilit implementasyonudur. lock() ve unlock() atomik olmalıdır. («ya yep ya hiç» çalıştırma mantığı) struct lock_type { int held = 0; } lockvar; void lock(lockvar) { while (lockvar->held); lockvar->held = 1; } void unlock(lockvar) { lockvar->held = 0; Çağıran kilidin bırakılmasını meşgulde bekler.

Karşılıklı Dışlama İçin Donanım Desteği Çoğu sistem kritik bölge kodunu yazmak için donanım desteği sağlamaktadır. Sonraki slaytlardaki çözümlerin hepsi kilitleme (kritik bölgeleri korumak için) fikrine dayanır. Tek işlemcilerde kesmeler kapatılabilir. Mevcut çalışan kod öncelik kullanılmaksızın çalışacaktır. Bu yöntem çok işlemcili sistemlerde genellikle çok verimsizdir. Modern makineler özel atomik (kesilemeyen) donanım talimatları sağlamaktadır. Bunlar bellekteki veriyi (memory word) test eden ve değerini atayan talimat ile iki bellek içeriğini takas eden talimatlardır.

test_and_set Talimatı boolean test_and_set (boolean *hedef) { boolean rv = *hedef; *hedef = TRUE; return rv: } Atomik olarak çalıştırılır. Geçilen parametrenin orijinal değerini döner. Geçilen parametrenin yeni değerini “TRUE” olarak ayarlar.

test_and_set() Kullanarak Çözüm lock paylaşımlı Bool değişkenine FALSE atanmıştır. do { while (test_and_set(&lock)) ; /* hiçbir şey yapma */ /* kritik bölge */ lock = false; /* kalan bölge */ } while (true);

compare_and_swap Talimatı int compare _and_swap(int *value, int expected, int new_value) { int temp = *value; if (*value == expected) *value = new_value; return temp; } Atomik olarak çalıştırılır. Verilen “value” parametresinin orijinal değerini döner. Sadece “value” ==“expected” olursa ”value” değişkenine verilen “new_value” parametresinin değerini atar. Yani takas ancak bu şartla gerçekleşir.

compare_and_swap Kullanarak Çözüm Paylaşımlı tamsayı “lock” 0 ilk değerini alır. do { while (compare_and_swap(&lock, 0, 1) != 0) ; /* hiçbir şey yapma */ /* kritik bölge */ lock = 0; /* kalan bölge */ } while (true);

test_and_set ile Bağlı Bekleyen Karşılıklı Dışlama do { waiting[i] = true; key = true; while (waiting[i] && key) key = test_and_set(&lock); waiting[i] = false; /* kritik bölge */ j = (i + 1) % n; while ((j != i) && !waiting[j]) j = (j + 1) % n; if (j == i) lock = false; else waiting[j] = false; /* kalan bölge */ } while (true);

Dönen Kilitlerdeki Sıkıntı Aşırı israfa neden olur! İplikler CPU üzerinde kilit dönüşünü bekler. Bol miktarda CPU zamanı yiyecek ve diğer ipliklerin işini yavaşlatacaktır. Kilitlemeye çalışan bir sürü iplik varsa ne olur? Dönen kilitleri yüksek seviye senkronizasyon yapıları için temel bileşen olarak kullanmak daha mantıklıdır. İplik 0 İplik 1 İplik 2 İplik 3 İplik 4 İplik 5 Süreçler/ İplikler Kritik Bölge Kilitli ve döner Kilitli ve döner Kilitli ve döner Kilitli ve döner Kilitli ve döner İplik tarafından kendi kritik bölgesinde kullanılabilecek CPU zamanını israf etmektedir.

Peterson’un Çözümü Yazılım tarafında bir çözümdür, donanım veya çekirdekle işi yoktur. Peterson.enter //pthread_mutex_lock(&myMutex) gibidir .. //kritik bölge detayları Peterson.exit //pthread_mutex_unlock(&myMutex) gibidir Sadece 2 süreç/iplik için çalışır. Bu çözüm işe yarar mı? lock = 1 (global değişken) Kritik bölgeye girmek isteyen bir iplik lock değerine bakar. (lock == 1) Doğruysa girer ve değeri azaltır. (lock--) Değilse, başka bir iplik azalttığı için girmez. İşe yaramaz zira lock da bir paylaşımlı global değişkendir. Başka koruma olmadan sadece bir değişken yetmez.

Peterson’un Çözümü LOAD ve STORE makine talimatlarının atomik olduğunu varsayalım. İki süreç iki değişken paylaşır: int turn; boolean flag[2]; turn değişkeni kimin kritik bölgeye girme sırasının geldiğini gösterir. turn = i, Pi sürecinin çalışabileceğini gösterir (i=0,1). flag dizisi bir sürecin kritik bölgeye girmeye hazır olup olmadığını gösterir. flag[i] = true, Pi sürecinin hazır olduğunu belirtir. (girmek istiyor)

Peterson’un Çözümü Pi için algoritma: (Pj diğer süreç) Girmek için hazır Diğer sürece sırayı devrediyor Meşgulde bekliyor

Peterson’un Çözümü flag[] turn Paylaşılan Değişkenler: SÜREÇ i (0) SÜREÇ j (1) do { flag[j] = TRUE; turn = i; while (flag[i] && turn == i); kritik bölge.. flag[j] = FALSE; kalan bölge.. } while (1) do { flag[i] = TRUE; turn = j; while (flag[j] && turn == j); kritik bölge.. flag[i] = FALSE; kalan bölge.. } while (1) flag[] turn Paylaşılan Değişkenler: i=0, j=1 yereldir.

Önceliğin Ters Yüz Olması (Priority Inversion) Düşük öncelikli bir sürecin kilitlediği kaynak nedeniyle yüksek öncelikli bir sürecin ihtiyaç duyduğu halde bu kaynağa erişememesi açmazıdır. Öncelik Kalıtımı: Yüksek öncelikli sürecin önceliği geçici olarak düşük öncelikli sürece verilir. Dolayısıyla orta öncelikli süreçler düşük öncelikli sürecin işi bitene kadar araya giremezler. Kaynak serbest kalınca, düşük öncelikli süreç başlangıçtaki öncelik seviyesine geri döner. Rastgele Yükseltme: Kilit tutan süreçler kritik bölgeden çıkana kadar öncelik değerleri rastgele yükseltilir. Windows görev yöneticisi bu mekanizmayı kullanır.

Ara Konu: C Kodu İçinde Assembly __asm__ {}; bloklarıyla istediğiniz makine dili kodunu yazabilirsiniz.

Ara Konu: Petri Netler 1962’ de Carl Adam Petri tarafından kimyasal işlemlerin modellenmesi için geliştirilmiştir. UML aktivite diyagramları gibi seçim, iterasyon ve koşut zamanlı çalıştırma içeren adımsal süreçler için bir grafiksel notasyon sağlar. Ayrıca çalışma semantiği için matematiksel tanımı ve süreç analizi için iyi geliştirilmiş bir matematik teorisi de bulunmaktadır.

Ara Konu: Petri Netler 4 temel bileşen içerir. Daireler durumları gösterir. Kutular gerçekleşmesi gereken aktivite ve koşulları da belirten bir durumdan diğerine geçişlerdir. Yönlü ve ağırlıklı oklar durumlar ve geçişler arasındadır. Bir aktivite, koşulun gerçekleşmesi için ona işaret eden durumlarda jeton bulunması gerekir. Jeton geçişin tetiklenmesini sağlar. Ok ağırlıkları durumu oluşturan jeton sayısını belirtir. Geçişin tetiklenmesi için bütün girişlerden gerekli sayıda jetona ihtiyaç vardır. Jetonlar bu sayede bir sonraki duruma aktarılır. Bir geçişle birden fazla duruma gidildiğinde jetonlar çoklanır.

Bloklayan Kilitler (Mutex Locks) Kritik bölgeye girmek isteyen bir ipliği bloklar, ipliği uyku moduna gönderir. Böylece diğer ipliklerin çalışması için CPU serbest kalır.

Yüksek Seviye Senkronizasyon İhtiyacı Kilitler senkronizasyon için kullanılan temel bir bileşendir. Kilitler pek çok iş için kullanılmakla birlikte programların bazen farklı ihtiyaçları olmaktadır. Örneğin herhangi bir sayıda ipliğin okuyabildiği ama sadece bir ipliğin yazabildiği bir paylaşımlı değişken olsun. Bu koddaki sıkıntı nedir? Okuyan() { lock(lockvar); mycopy = shared_var; unlock(lockvar); return mycopy; } Yazan() { lock(lockvar); shared_var = NEW_VALUE; unlock(lockvar); }

Semaforlar (Semaphores) İlk değeri atanmış, paylaşımlı sayaçlardır. Edsger Dijkstra tarafından 1960’larda tasarlanmıştır. Semaforlar için iki atomik işlem tanımlıdır: P() veya down() veya wait() Felemenkçe «proeberen» (test) Semafor değerinin sıfırdan büyük olmasını bekler sonra azaltır. V() veya up() veya post() veya signal() Felemenkçe «verhogen» (arttır) Semafor değerini 1 arttırır.

1 Değeri Atanmış Semafor

İplik 1 wait() Çağırır ve Devam Eder Thread 1 wait() Semafor Semafor değeri önce: 1 Semafor değeri sonra: 0

İplik 2 wait() Çağırır ve Bloklar Thread 2 wait() Z z Semafor Semafor değeri önce: 0 Semafor değeri sonra: -1

İplik 3 signal() Çağırır Thread 3 signal() Z z Thread 2 wait() Semafor Semafor değeri önce: -1 Semafor değeri sonra: 0

İplik 4 signal() Çağırır ve Devam Eder Thread 4 signal() Semafor Semafor değeri önce: 0 Semafor değeri sonra: 1

C Semafor İşlemleri Pthreads fonksiyonları: #include <semaphore.h> int sem_init(sem_t *s, 0, unsigned int val);} /* s = val */ int sem_wait(sem_t *s); /* P(s), down(s) */ int sem_post(sem_t *s); /* V(s), up(s), signal(s)*/

Semaforlar Niye Kullanışlıdır İkili semafor aslında bir kilittir. Semafor; değeri 0 veya 1’ de başka bir değer olarak ayarlanabildiğinde anlamlı olur. Kaynak tahsisi gibi senkronizasyon problemlerinde semafor değerini eldeki kaynak miktarı olarak atayıp kullanabilirsiniz.

Semaforların Çözemedikleri Semaforların gücünün çoğu eşleşmeyen wait() ve signal() çağrılarından türemektedir. Kilitlerdeki lock() ve unlock() eşleşme zorunluluğu yoktur. Bu nedenle semaforla sıkıntı yaşamak daha kolaydır. Senkronizasyon için daha temiz ve iyi tanımlı bir yapı (dil desteği) gerekmektedir.

Monitörler İşletim sistemi dışında programlama dilinden de yardım almaktır. Süreç/iplik senkronizasyonu için yüksek seviye soyutlamadır. Java desteklemektedir, C ise ancak semafor çeşitlemesi yapabilir. Derleyici kodunuzun kritik bölgelerinin korunmasını garantiye alır. Kodun kritik bölgesi belirtilir, monitör içine alınır ve derleyici koruma kodunu yerleştirir. Semafor kullanarak monitör implementasyonu derleyici yazarı/dil geliştiricisinin derdidir, uygulama geliştiricisi işine bakar.

Paylaşılan veriye erişen 18/02/08 Monitörler Paylaşılan Veri Paylaşılan veriye erişen metodlar kilitlenmemiş

Paylaşılan veriye erişen 18/02/08 Monitörler Paylaşılan Veri Paylaşılan veriye erişen metodlar kilitli zzzz... Uyuyan iplik artık monitörün içinde değildir. Bekleme kuyruğunda da değildir.

Paylaşılan veriye erişen 18/02/08 Monitörler Paylaşılan Veri Paylaşılan veriye erişen metodlar kilitli Monitör kilitli kalır! (Farklı bir iplik kilidin sahibidir.) zzzz... notify()

Paylaşılan veriye erişen 18/02/08 Monitörler Paylaşılan Veri Paylaşılan veriye erişen metodlar kilitli notify()

Paylaşılan veriye erişen 18/02/08 Monitörler kilitli Paylaşılan Veri Paylaşılan veriye erişen metodlar İpliklerin monitöre hangi sırada geldiklerinin hiçbir garantisi yoktur. (FIFO olmak zorunda değildir!)

Java’da Monitörler Her Java nesnesinde bir kilit ve durum değişkeni vardır. Bunlar için ayrıca sınıf tanımları yoktur. Her nesne bir monitördür/nesnenin bir monitörü vardır Bir nesnenin monitörünün içinde en fazla bir iplik olabilir. Bir iplik bir nesnenin monitörüne “synchronized” tanımlanmış bir metot çalıştırarak girer. Aynı sınıfta “synchronized” veya diğer metotlar karışık kullanılabilir. Her nesneye durum değişkeni olarak davranılabilir. wait() :  Mevcut ipliği askıya alır. notify() : Bekleme listesinden rastgele bir ipliğe (T) bildirim gönderir. T hedef nesne için (en azından notify çağrısı yapan iplik kilidi serbest bırakana kadar daima bloklamasını sağlayan) senkronizasyon kilidini tekrar elde etmelidir. Eğer başka bir iplik kilidi önce elde ederse bloklamaya devam edecektir. notifyAll() : Askıdaki ipliklerin hepsine bildirim gönderir.

Java’da Monitör Örneği 18/02/08 Java’da Monitör Örneği class Sayac { private int miktar = 0; public void synchronized arttir() int n = miktar; miktar = n+1; } Sayac c, d; /* Paylaşılan nesneler */ İplik A İplik B … c.arttir(); … c.arttir(); İplik A arttir()çalıştırırken İplik B arttir()çağırdığında, İplik B monitörden çıkana kadar bloklanacaktır. «synchronized» bir metot kritik bölge demek değildir! Senkronizasyon kodun kendisiyle (sınıf tanımı) değil nesne oluşumlarıyla (object instance) ilişkilidir. Dolayısıyla c.arttir(), d.arttir() ile aynı anda çalıştırılabilir.

Durum Değişkenleri (Condition Variables) Kavramsal olarak bir durum değişkeni bir ipliğin bazı ifadelerin doğru olana kadar beklemesi üzerine monitörle ilişkili bir iplik kuyruğudur. İplikler durum değişkenlerini; bazı şartlar sağlanana kadar beklerken ayrıcalıklı erişimden geçici olarak vazgeçmek için, tekrar ayrıcalıklı erişim elde etmeden ve işlerine devam etmeden önce, koşulların sağlandığını diğer ipliklere sinyal geçmek için kullanabilirler.

Pthreads Senkronizasyonu Pthreads API İ.S bağımsızdır. Mutex kilitleri ve durum değişkenleri sağlar. Bazı eklentileri okuma-yazma kilitleri ve dönen kilitler de içerir.

Linux Senkronizasyonu 2.6 çekirdek sürümü öncesinde Linux kısa kritik bölgeleri oluşturmak için kesmeleri iptal ediyordu. 2.6 ve sonrasında tamamen öncelik kullanımlı yapılmaktadır. Linux semaforlar, atomik tam sayılar, dönen kilitler ve bunların okur- yazar çeşitlerini sağlamaktadır. Tek işlemcili sistemde dönen kilitlerin yerine çekirdek öncelik kullanımını açma/kapama kullanılır.

Solaris Senkronizasyonu Çok işlevlik, çok iplikli çalışma ve çok işlemcililik desteği için çeşitli kilitler tanımlamaktadır. Verim için veriyi kısa kod parçalarından koruyan uyarlanabilir mutex yapıları kullanır. Durum değişkenleri, veriye erişmesi gereken uzun kod bölümleri için okur-yazar kilitler ve uyarlanabilir mutex veya okuma-yazma kilidi elde etmeyi bekleyen ipliklerin listesini sıralayan turnikeler kullanır. Öncelik kalıtımı turnikedeki çalışan bir ipliğe kendi turnikesindeki iplikler arasında en yüksek önceliği verir.

Windows Senkronizasyonu Tek işlemcili sistemlerde global kaynaklara erişimi korumak için kesme maskeleri kullanır. Çok işlemcili sistemlerde dönen kilitler kullanır. Dönen kilitli iplik öncelik kullanımına maruz bırakılmaz. Ayrıca kullanıcı tarafında mutex, semafor, olay ve sayaç (timer) olarak davranabilen sevkedici nesneler sağlar. Olaylar durum değişkeni gibi davranırlar. Sayaçlar zaman dolduğunda bir veya daha fazla ipliğe bildirim yapar. Sevkedici nesneler ya sinyalli durumda (nesne müsait) veya sinyalsiz durumda (iplik bloklanacak) olurlar.

Üretici Tüketici Problemi Java’da Bir Çözüm class Buffer { private char [] buffer; private int count = 0, in = 0, out = 0; Buffer(int size) { buffer = new char[size]; } public synchronized void insert(char c) { while(count == buffer.length) { try { wait(); } catch (InterruptedException e) { } finally { } System.out.println("Producing " + c + " ..."); buffer[in] = c; in = (in + 1) % buffer.length; count++; notify(); public synchronized char remove() { while (count == 0) { char c = buffer[out]; out = (out + 1) % buffer.length; count--; System.out.println("Consuming " + c + " ..."); return c;

Yemek Yiyen Düşünürler Problemi Bir düşünür (süreç) yemek için iki çatala (kaynaklar) ihtiyaç duymaktadır. Bir düşünür çatalı eline aldığı sürece komşuları çatala dokunamaz.

Yemek Yiyen Düşünürler Problemi Bir düşünür (süreç) yemek için iki çatala (kaynaklar) ihtiyaç duymaktadır. Bir düşünür çatalı eline aldığı sürece komşuları çatala dokunamaz. (karşılıklı dışlama)

Yemek Yiyen Düşünürler Problemi Bir düşünür (süreç) yemek için iki çatala (kaynaklar) ihtiyaç duymaktadır. Bir düşünür çatalı eline aldığı sürece komşuları çatala dokunamaz.

Yemek Yiyen Düşünürler Problemi Düşünür 2 durumdadır: Yiyor (çatal gerekir) ve düşünüyor (çatal gerekmez). Paralellik istenmektedir, mesela 3 veya 4, 1 yiyorken de yiyebilmelidir. (0 ve 2 değil) Ölümcül kilitlenme olmamalı, yani her biri diğerini belirsiz bir süre boyunca beklememelidir. Düşünürlerin aşırı beklemekten aç kalmaları ve vefat etmeleri de istenmemektedir. Amaç düşünürlerin yeme-düşünme döngüsünü sağlamaktır.

Yemek Yiyen Düşünürler Problemi İlk Deneme Koşut zamanlı ancak kilitlenme önlemeyen bir semafor çözümü Semaphore forks[5]; //ilk değer 1 (masada 5 düşünür varsayıyoruz) do { wait( forks[i] ); wait( forks[ (i + 1) % 5] ); // ye signal( forks[i] ); signal( forks[ (i + 1) % 5] ); // düşün } while(TRUE); Soru: Ölümcül kilitlenme mümkün müdür?

Yemek Yiyen Düşünürler Problemi Elbette mümkündür zira: 4 sol çatalı alır. Ara geçiş 3 sol çatalı alır. Ara geçiş, … 0 sol çatalı alır. Ara geçiş. 4 (0’ın tuttuğu) sağ çatalı almak ister. Geçişlerin bu şekilde olması muhtemel olmasa da mümkündür. Kilitlenme tehlikesi olmaksızın bir çözümü yine semaforlar vermektedir. Eğer sağ çatalı alamıyorsan solu yerine bırak. Her iki çatalı da bir anda al. (atomik olarak)

Okur Yazar Problemi Bir veri kümesi okur (verileri sadece okuyabilir) ve yazar (verileri okuyabilir ve değiştirebilir) türünden koşut zamanlı süreçler arasında paylaşılmaktadır. Çok sayıda okurun aynı anda okumasına ve bir anda sadece bir yazarın değiştirmesine müsaade etmek nasıl mümkündür? Paylaşılan veriler Veri kümesi İlk değeri 1 olarak atanmış rw_mutex semaforu İlk değeri 1 olarak atanmış mutex semaforu İlk değeri 0 olarak atanmış read_count tam sayı değişkeni Çevrimiçi otobüs, uçak rezervasyonu, çok iplikli ön bellekli Web proxy

Okur Yazar Problemi Okur Sürecin Yapısı Yazar Sürecin Yapısı do { wait(mutex); read_count++; if (read_count == 1) wait(rw_mutex); signal(mutex); ... /* okuma gerçekleşir */ ... wait(mutex); read count--; if (read_count == 0) signal(rw_mutex); } while (true); do { wait(rw_mutex); ... /* yazma gerçekleşir */ ... signal(rw_mutex); } while (true); Bir okur sadece, bir yazarın yazmayı tamamlamasını beklemelidir. Bir okur diğer okurların okumayı tamamlamalarını beklememelidir. Bir yazar diğer yazarların yazmayı bitirmelerini beklemelidir. Bir yazar bütün okurların okumayı bitirmelerini beklemelidir.

Değerlendirme signal(semafor) asla bloklamaz, her zaman ilerletir. wait(semafor) bloklayabilir; eğer semaforun mevcut değeri 0 ise bloklayacak, 0’ dan büyükse azalttıktan sonra ilerleyecektir. Semafor değerine doğrudan erişilemez, if(semafor == i) türünden mukayeselere müsaade edilmemektedir.

Okur Yazar Problemi Çeşitleri Yazar paylaşılan nesneyi kullanma yetkisini alana kadar hiçbir okur bekletilmez. Yazar müsait olunca mümkün olan en kısa zamanda yazmayı gerçekleştirir. İki çeşit de farklı çeşitlemelere götüren açlık durumları içerebilir. Bazı sistemlerde bu problem çekirdek tarafından sağlanan okur-yazar kilitleriyle çözülmektedir.

Sigara İçenler Problemi Sigara içmek için tütün, kağıt ve kibrite (kaynaklar) ihtiyaç vardır. Üç sigara içicinin (süreçler) her birinde sırayla sınırsız tütün, kağıt ve kibrit vardır. Dördüncü biri (İ.S.) masaya rastgele iki tür malzeme koyar. İçicilerden biri malzemeleri alarak sigarasını yakar. Sistemi kilitlenme olmadan senkronize ediniz. Ek kısıtlar: Dördüncü kişi kodu değiştirilemez. Çözümde koşullu ifadeler (if) kullanılamaz. Bu kısıtlar semaforla çözümü imkansız kılar. YASAL UYARI: SİGARA SAĞLIĞA ZARARLIDIR!

Sigara İçenler Problemi Çözümü Dördüncü kişi: Malzemeleri alacak içiciyi uyandırır ve uykuya geçer. İçici sigarayı içerken dördüncüyü uyandırır. lock 1, diğer semaforlar 0 ilk değerlidir. 1 while(1) { 2 P( lock ); //Semaforu indir 3 randNum = rand(1,3); // 1-3 arası rastgele sayı seç 4 if ( randNum == 1 ) { 5 // Masaya tütün koy 6 // Masaya kağıt koy 7 V( smoker_match ); // Kibritli içiciyi uyandır 8 } else if ( randNum == 2 ) { 9 // Masaya tütün koy 10 // Masaya kibrit koy 11 V( smoker_paper ); // Kağıtlı içiciyi uyandır 12 } else { 13 // Masaya kibrit koy 14 // Masaya kağıt koy 15 V( smoker_tobacco ); } // Tütünlü içiciyi uyandır 16 V( lock ); //Semaforu kaldır 17 P( agent ); // Dördüncü uykuya geçer 18 } İçici sigarasını içerken dördüncü yeniden malzemeler koyar ve alakalı içiciyi uyandırır.  Tütün sahibi içici (diğerlerine de uyarlanabilir) 1 while(1) { 2 P( smoker_tobacco ); // Uykuya geç 3 P( lock ); 4 // Kibriti al 5 // Kağıdı al 6 V( agent ); 7 V( lock ); 8 /* Sigarayı iç ve uyu */ } İçici, istediği malzemeleri almak için dördüncü tekrar uyandırana kadar uyur. YASAL UYARI: SİGARA SAĞLIĞA ZARARLIDIR!

Uyuyan Berber Problemi Bir berber dükkanında N sandalyeli bekleme odası ve berberin oturduğu berber odası vardır. Eğer müşteri yoksa berber uyur. Eğer bütün sandalyeler doluyken dükkana müşteri gelirse, müşteri geri gider. Berber meşgulse ama oturacak yer varsa gelen müşteri boş bir yere oturur. Berber uyuyorsa gelen müşteri berberi uyandırır.

Uyuyan Berber Problemi Semafor Şablonu semaphore customer; init(customer,0); // hizmet bekleyen müşteri sayısı semaphore barber; init(barber,0); // müşteri bekleyen berber sayısı semaphore mutex; init(mutex,1); // karşılıklı dışlama için int waiting = 0; //sandalyelerde oturan müşteriler void barberThread(){ while (1) { ………………. cutHair(); ……………. } void customerThread(){ ……………….. getHairCut(); // bütün sandalyeler doluysa çalıştırılmayabilir ………………

Uyuyan Berber Problemi Monitör Şablonu monitor BarberShop{ condition waitingForCustomers, waitingForBarbers; int waiting = 0; // sandalyede bekleyen müşteri sayısı void barber(){ …………………. cutHair(); ………………. } void customer(){ getHairCut(); // bütün sandalyeler doluysa çalıştırılmayabilir ……………… void barberThread(){ while(1) BarberShop.barber(); void customerThread(){ BarberShop.customer();

Uyuyan Berber Problemi B: Müşteri yokken berber uyuyor mu? BM: İlk müşteri berberi uyandırıp saçını kestiriyor mu? BMM: İkinci müşteri berberin ilk müşterinin tıraşını bitirmesini bekliyor mu? BMMMMMMM: 7. müşteri tıraşını olmadan ayrılır mı? BMMMMM: Berber ilk müşterinin tıraşını bitirdikten sonra bekleyen bir müşteriyi uyandırıyor mu? Son olarak bu çözüm verimli midir? İhtiyaç duyulandan fazla bildirim sinyali gönderme veya daha fazla değişken kullanma iyi bir uygulama değildir.

18/02/08 Büyük Resim.jpg Esas mesele senkronizasyonun doğru biçimde yapılmasının zor olmasıdır. Kilitler, semaforlar, durum değişkenleri, monitörlerden hangisini seçmeli? Kilitler çoğu durum için oldukça basittir. Sıkıntı: En verimli çözüm olmamasıdır. Mesela standart bir kilitin içinde çok okuyan fakat bir yazana müsaade edilemez. Durum değişkenleri ipliklerin bir kilidi tutarken uyumalarını sağlar. Mesa ve Hoare semantiğinden hangisini kullandıklarını anladığınızdan emin olunuz. Semaforlar genel işlevsellik sağlar. Fakat aynı zamanda işleri berbat etmek de çok kolaydır.