Bu repo Java ile sıfırdan yazılmış semaphore ve lock kullanarak Reader-Writer probleminin iki farklı çözümünü içerir.
Reader-Writer işletim sistemlerinin en klasik eşzamanlılık (concurrency) problemlerinden biridir.
- Birden fazla okuyucu aynı anda okuma işlemini gerçekleştirebilir — veriyi tehlikeye atmaz.
- Yazıcı çalışırken ne kimse okuyabilir ne de yazabilir.
- Okuyucu çalışırken başka bir yazıcı yazamaz.
Amaç: veriyi korurken thread'lerin en optimize şekilde çalışması.
| Dosya | Açıklama |
|---|---|
OS_ReaderWriter.java |
Klasik çözüm — okuyucuya öncelik verir, writer starvation içerir. |
OS_ReaderWriter1.java |
Adil çözüm — FIFO kullanarak starvation'ı ortadan kaldırır. |
Her iki dosyada da Java'nın java.util.concurrent kütüphanesi kullanılmadı. Semaphore sıfırdan synchronized, wait() ve notifyAll() ile implemente edildi.
class Semaphore {
private int count;
public Semaphore ( int c ) {count= c;}
public synchronized void acquire() throws InterruptedException {
while (count==0 ) wait( );
count--;}
public synchronized void release() {
count++ ;
notifyAll();
}}İlk okuyucu geldiğinde yazıcı kilidini tutar, son okuyucu bittiğinde bu kilidi serbest bırakır. Bu sayede okuyucular aynı anda veriyi okuyabilir.
Bu tasarımda okuyucular her zaman önceliklidir. Sürekli yeni okuyucu geldiği durumda yazıcı sonsuza kadar bekler. Buna "Writer Starvation Problem" denir.
R-7 wants to read
R-7 START reading
R-9 wants to read
R-9 START reading
R-10 wants to read
R-10 START reading
W-3 wants to write -- W-3 ve W-1 çok erken geldiler
W-1 wants to write
R-3 wants to read
R-3 START reading
...
R-11 END reading --ama ancak tüm okuyucular bittikten sonra yazıcılar başladı
W-3 START writing
W-3 END writing
W-2 START writing
W-2 END writing
W-1 START writing -- W-1 en erken gelmişti, en son yazdı
W-1 END writing
=== Test finished ===
*W-1 ve W-3, okuyuculardan önce gelmesine rağmen tüm okuyucuların bitmesini beklediler bu yüzden en sona düştüler. Starvation çıktıda açıkça görülüyor.
Starvation problemini çözmek için geliştirildi. Temel fikir: önce gelen önce hizmet alır.
Her thread, kilide girmek istediğinde bir Request nesnesi oluşturur ve bekleme kuyruğuna girer. cevap almadan işlem yapamaz.
- Kuyruğa ilk 2 okuyucu sonra bir yazıcı ve takrar okuyucuların geldiği senaryoda sonradan gelen okuyucular yazıcının işlemini bitirip cevap döndürmesini bekler.
Sıra: R1, R2, W1, R3, R4 gelirse
- R1 ve R2 aynı anda okur
- W1 sırasını bekler
- R3 ve R4, W1 bitmeden okuyamaz
- W1 yazar
- R3 ve R4 aynı anda okur
Böylece hem okuyucular aynı anda okuma işlemini geröekleştirirken (concurrency) hem writer starvation ortadan kalkar.
R-2 wants to read
R-2 START reading
R-3 wants to read
R-3 START reading
R-4 wants to read
R-4 START reading
R-1 wants to read
R-1 START reading
---> W-1 wants to write
R-2 END reading
---> W-2 wants to write
R-6 wants to read
R-3 END reading
R-5 wants to read
R-4 END reading
R-1 END reading
---> W-1 START writing
---> W-1 END writing
---> W-2 START writing
---> W-2 END writing
R-5 START reading
R-6 START reading
R-6 END reading
R-5 END reading
------- test finished -------
Çıktıdan görüldüğü üzere yazıcılar en sona yığılmadı. FIFO sırası korundu.
| Sınıf 1 (Readers Öncelikli) | Sınıf 2 (FIFO Lock) | |
|---|---|---|
| Eş zamanlı okuma | var | var |
| Writer Starvation | oluşabilir | Yok |
| Adillik | okuyucuya öncelikverir | varış sırasına göre |
| Kullanım | Okuma ağırlıklı uygulamalar | Dengeli sistemler |