Jumat, 15 Maret 2019

Munculnya konsep sistem operasi multitasking memungkinkan sejumlah proses aktif bersamaan pada suatu sistem operasi. Proses-proses ini pada hakekatnya saling memengaruhi karena menggunakan prosesor dan memori yang sama. Konsep proses yang memiliki ruang alamat logika yang independent dan terisolasi dari proses lain, merupakan salah satu cara agar perebutan terhadap sumber daya tersebut tidak perlu ditangani langsung oleh pemrogram aplikasi, tapi ditangani oleh sistem operasi dan dibantu dukungan perangkat keras seperti MMU (Memory Management Unit). Sekalipun demikian, ada kalanya proses-proses yang berjalan tersebut saling bekerja sama sehingga sistem operasi harus menyediakan fasilitas komunikasi antar proses (IPC, Inter Process Communication).


Ada 2 macam model komunikasi antar proses yang saling bekerja sama,


yaitu:


1. Model bertukar pesan (message passing)


2. Model berbagai pakai memori (shared memory).

Gambar 4.6 menunjukkan perbedaan kedua model tersebut di atas.




Gambar 4.6 Model komunikasi antar proses


Mekanisme message passing (a) melibatkan intervensi sistem operasi secara langsung. Misalnya proses A hendak menyampaikan suatu pesan M ke proses B maka proses A akan mengirimkan pesannya ke kernel sistem operasi (1), yang kemudian diteruskan ke proses B (2). Perlu dicatat, pesan M harus mengandung informasi alamat tujuan dari pesan tersebut. Hal ini sama halnya jika kita ingin mengirim kartu pos ke orang lain. Pada kartu pos dicantumkan pesan dan alamat tujuannya. Kemudian kita menyampaikan kartu pos tersebut ke kantor pos, dan kemudian pihak kantor pos menyampaikan pesan tersebut ke pihak penerima.


Mekanisme IPC kedua adalah berbagi pakai memori seperti pada Gambar 4.6(b). Mekanisme ini melibatkan sistem operasi pada saat mengalokasi- kan memori ke proses-proses yang akan saling berkomunikasi lewat fasilitas ini. Caranya adalah bagian tertentu dari ruang alamat dua proses tersebut dipetakan ke suatu lokasi memori fisik yang sama sehingga proses-proses tersebut dapat menulis maupun membaca dari lokasi memori ini. Proses A mengirimkan pesan dengan cara menulis pesannya di ruang memori bersama ini. Proses B menerima pesan tersebut dengan membacanya dari ruang memori tersebut. Perhatikan, dari perspektif masing-masing proses, mereka menulis atau membaca ruang alamat mereka sendiri. Pengaksesan ke memori bersama ini umumnya mem- butuhkan sinkronisasi agar tidak terjadi perebutan akses bersamaan yang dapat menyebabkan ketidakkonsistenan data yang diakses.


4.3.1 KOMUNIKASI LANGSUNG VS KOMUNIKASI TIDAK LANGSUNG


Model komunikasi message-passing sendiri dapat dikelompokkan dalam dua bentuk, yaitu:


1. Komunikasi langsung dan


2. Komunikasi tidak langsung.


Pada komunikasi langsung seperti pada Gambar 4.7(a), alamat identitas atau alamat penerima dinyatakan secara eksplisit dalam sintak pengiriman pesan, yaitu:


Send (pesan, proses tujuan)


Sedangkan pada komunikasi tidak langsung seperti pada Gambar 4.7(b). pengiriman dan penerimaan pesan dilakukan mengunakan suatu per- antara yang disebut dengan mailbox ataupun port. Jadi pengirim akan menyampaikan pesan ke mailbox dengan sintak:


Send (pesan, alamat mailbox)


Pada hakekatnya pengirim tidak menentukan secara rinci proses mana yang menjadi tujuan pesan. Setiap proses yang dapat membaca dari mailbox yang digunakan, otomatis dapat menjadi pihak penerima pesan. Penerima mengambil pesan dari mailbox dengan sintak:


Receive (pesan, alamat mailbox)



Gambar 4.7. Komunikasi langsung (a) dan komunikasi tidak langsung (b)


Ciri-ciri dari komunikasi langsung antara lain:


1. Terdapat sambungan yang dapat bekerja secara otomatis antara proses proses yang ingin berkomunikasi


2. Tiap sambungan menghubungkan tepat dua proses, antar setiap pasangan proses terdapat tepat satu jalur sambungan


3. Sambungan dapat bersifat satu arah (unidirectional), namun biasanya


bersifat dua arah (bidirectional).


Adapun ciri-ciri komunikasi tidak langsung antara lain:


1. Komunikasi antar dua proses dapat terjadi jika dua-duanya memiliki akses ke suatu mailbox yang sama.


2. Tiap mailbox dapat menghubungkan lebih dari dua proses, dan dimungkinkan terdapat lebih dari satu sambungan untuk setiap pasangan proses yang hendak berkomunikasi.setiap sambungan akan menggunakan suatu mailbox seperti yang diperlihatkan pada Gambar 4.8


3. Sambungan dapat bersifat satu arah, tetapi umumnya bersifat dua arah.


Gambar 4.8 menunjukkan komunikasi tak langsung antara proses-proses dengan menggunakan lebih dari satu mailbox. Dari gambar terlihat ada tiga sambungan (link) komunikasi tak langsung yang mungkin dilakukan.

Pertama adalah antara P1 dan P3 lewat M2 dan komunikasinya bersifat bidirectional. Kedua, antara P1 dan P3 lewat M1 dan komunikasinya bersifat unidirectional, yaitu dari P1 ke P3 saja dan tidak sebaliknya. Ketiga, antara P1 dan P2 lewat M1 dan komunikasinya bersifat unidirectional yaitu dari P1 ke P2 saja. Perhatikan, sekalipun P2 dan P3 punya akses ke M1, namun keduanya tidak dapat menyelenggarakan komunikasi. Ini dikarenakan keduanya hanya memiliki akses baca dari M1.


Syarat agar dua proses dapat berkomunikasi lewat suatu mailbox adalah salah satu proses (proses penerima), memiliki hak baca ke mailbox. sedangkan proses lainnya (proses pengirim), memiliki hak tulis ke mailbox tersebut.




Gambar 4.8 Komunikasi tak langsung lewat sejumlah mailbox


Isu lain komunikasi tak langsung adalah kepemilikan mailbox, atau pihak yang berhak membaca dari mailbox. Kepemilikan mailbox dapat bersifat pribadi (private) ataupun umum (public).


Jika kepemilikan mailbox bersifat pribadi, maka hanya pemilik tunggal mailbox tersebut yang berhak membaca pesan yang masuk ke mailbox tersebut. Analoginya adalah kotak surat pribadi pada setiap rumah, di mana kotak surat tersebut adalah milik rumah tersebut. Pihak-pihak lain dapat mengirimkan surat ke kotak surat tersebut, tetapi hanya pemilik rumah yang berhak membaca surat dari kotak surat tersebut.

Kepemilikan mailbox juga dapat bersifat umum ataupun digunakan bersama oleh sekelompok pengguna atau proses. Dalam skenario ini, semua proses dapat mengirimkan pesan ke mailbox tersebut, dan terdapat sejumlah proses lainnya yang dapat membaca dari mailbox tersebut. Analoginya adalah fasilitas mailing-list pada email sehingga siapa saja dapat mengirim pesan ke mailing-list, dan terdapat sejumlah pengguna, yaitu anggota mailing-list yang dapat membaca pesan-pesan yang masuk ke mailbox mailing list tersebut.


4.3.2 IMPLEMENTASI MESSAGE BUFFER PADA MESSAGE PASSING


Komunikasi message passing sering membutuhkan penggunaan message buffer. Mengapa hal ini dibutuhkan? Message buffer diperlukan terutama karena umumnya kapasitas atau bandwidth sambungan (link) komunikasi terbatas. Sebagai contoh, link komunikasi hanya mampu mengirimkan satu pesan setiap saat, padahal pesan yang harus dikirimkan adalah dua atau tiga setiap saat. Untuk lebih konkretnya, lihat contoh pada Gambar 4.9. Misalnya proses A secara berturut-turut mengirimkan pesan Mab ke proses B dan pesan Mac ke proses C lewat link yang sama. Agar kedua pengiriman pesan tersebut dapat dilakukan secara asinkron maka butuh diimplementasikan message buffer pada sisi proses A sebagai proses pengirim. Jadi pesan Mac dan Mab akan di-buffer terlebih dahulu dan dijadwal untuk dikirimkan lewat link komunikasi jika dimungkinkan, yaitu pada saat tidak digunakan oleh proses lain. Keuntungan lain dari memakai message buffer adalah jika terjadi kesalahan dalam transmisi data lewat sambungan (link) komunikasi maka pesan dapat dikirim ulang.


Message buffer dapat pula diimplementasikan pada titik singgah (node) sepanjang link komunikasi. Hal ini diperlukan jika sebagian link komuni- kasi digunakan bersama oleh proses lainnya. Misalnya proses D yang pada saat bersamaan hendak mengirim pesan Mah ke proses B. Link komunikasi proses D ke B bertabrakan dengan link komunikasi proses A ke B sepanjang node X ke proses B. Agar kedua pengiriman tersebut dapat diakomodasi maka pada node X, butuh diimplementasikan message buffer

yang akan menampung sementara pesan Mah dan Madh, dan menjadwalkan pengiriman pesan tersebut ke B.


Message buffer dapat juga diimplementasi pada sisi penerima, proses B. Ini diperlukan jika pesan dapat masuk dari link-link yang berbeda secara bersamaan, misalnya ada link juga dari proses E, ataupun karena kecepatan proses B mengolah pesan lebih lambat dibanding kecepatan masuknya pesan-pesan baru.


Gambar 4.9 Penggunaan Message Buffer pada komunikasi message passing


Message buffer dapat diimplementasikan dalam bentuk-bentuk antrian berikut:


1. Antrian kapasitas nol (Zero Capacity Queue)
Antrian dengan kapasitas nol atau dengan kata lain tidak meng- gunakan buffer message. Pengirim harus menunggu sampai pesan sampai ke penerima baru kemudian dapat mengirimkan pesan selan- jutnya. Dengan kata lain komunikasi pengiriman pesan berlangsung secara sinkron. Selain itu jika link komunikasi sedang digunakan untuk pengiriman pesan oleh proses lain maka link tersebut tidak dapat memproses permintaan baru untuk pengiriman pesan.


2. Antrian kapasitas terbatas (Bounded Capacity Queue)
Antrian memiliki batas kapasitas pesan yang dapat ditampung, misalnya sebesar n pesan. Jika antrian sudah penuh maka pengiriman pesan berikutnya harus ditunda lebih dahulu.


3. Antrian kapasitas tidak terbatas (Unbounded Capacity Queue)
Antrian memiliki kapasitas penampungan yang tak terbatas. Pengirim pesan tidak perlu menunggu. Pengiriman pesan dapat berjalan asin- kron sepanjang waktu.

 4.4.1 KONSEP SINKRONISASI


    Sistem konkuren umumnya memungkinkan proses-proses melakukan akses secara konkuren ke suatu sumberdaya yang dibagipakai bersama. Hal ini menimbulkan race condition, yaitu kondisi saat lebih dari satu proses berusaha mengakses suatu sumberdaya pada suatu saat yang bersamaan. Race condition ini membawa dampak terhadap konsistensi dan keabsahan kondisi dari sumberdaya yang diakses tersebut.

    Untuk menjelaskan masalah yang muncul akibat race condition, dicontohkan Aplikasi Transfer Uang pada Gambar 4.10. Sebaga contoh, dua proses terpisah sedang melakukan transfer uang sebesar 10 (proses P1), dan sebesar 20 (proses P2) ke suatu nomor rekening yang sama yang memiliki saldo awal sebesar 100. Jika kedua aktivitas transfer uang tersebut berjalan secara benar, maka saldo akhir rekening mestinya 130. Namun, terlihat dari contoh, bahwa jika proses transfer P1 dan P2, yang berjalan terpisah namun konkuren tidak dikoordinasi dengan baik maka mungkin akan terjadi race condition dan menghasilkan saldo akhir yang salah, yaitu 110 atau 120.

    Di manakah letak permasalahannya? Permasalahannya terletak pada kode yang melakukan akses ke sumber-daya yang digunakan bersama oleh proses P1 dan P2. yaitu variabel balance atau saldo rekening. Kedua proses P1 dan P2 membaca nilai balance dan mengubah, atau lebih tepatnya menjumlahkan dengan suatu nilai sesuai dengan uang yang ditransfer oleh masing-masing proses.

Kode bahasa C yang melakukan pembacaan dan pengubahan (yaitu balance+= amount) jika dikompilasi akan menghasilkan tiga instruksi biner yang dalam Bahasa Assembly adalah:

  1. Load (membaca data dari memori, yaitu variabel balance, ke register)
  2. Add (menjumlahkan suatu nilai, yaitu uang yang ditransfer ke register)
  3. Store (menyimpan nilai register ke memori, yaitu variabel balance).

    Ketiga instruksi biner tersebut merupakan satu kesatuan dan harus di- jalankan secara atomik atau utuh. Artinya selama eksekusi ketiga instruk- si biner ini harus dipastikan tidak ada proses lain yang juga membaca atau mengubah nilai variabel balance.

    Jika aplikasi di atas dijalankan pada model client-server, server yang melayani permintaan transfer dari proses P1 dan P2, sangat mungkin melakukan penjadwalan eksekusi intruksi Pl dan P2 seperti yang ditunjukkan pada Gambar 4.10. Misalnya prosesor server menjadwal eksekusi perintah P1 (load), kemudian P2(load), kembali sedang ke Pl (add), kemudian P2 (add), P1 (store) sehingga variabel balance menjadi 110, kemudian P2 (store) sehingga akhirnya variabel balance menjadi 120.

    Secara logika, hasil ini salah, karena nilai seharusnya adalah 130. Kondisi ini terjadi karena prosesor server tidak melakukan perintah Load, Add, Save dari proses P1 secara atomik, tetapi justru menyelanya dengan eksekusi proses P2 yang juga mengakses variabel balance yang sama. Kondisi perebutan penjadwalan prosesor server dan pengaksesan variabel balance inilah yang disebut dengan race condition. Kondisi ini menghasilkan perhitungan akhir yang tidak valid.


SAMAGE ASSEM


void deposites


Add Rong whoun Stove Reg, balance


palance amour


P1


One possible proet of


беровец 10)


Balance powal100


Cru sched


deposit 20


add20egister, giving 120


Pistons 110 in balance


Satance (shton 128 Balance (vehananyaj130


P2 stores 120 in belance


Contat: Mace Con












Gambar 4.10 Kondisi Race Condition pada Kasus Transfer Uang


    Perlu dicatat, kondisi akhir yang tidak valid ini hanya terjadi jika timing eksekusi fungsi transfer dari kedua proses terjadi hampir "bersamaan" sedemikian rupa sehingga prosesor menjadwalkan 3 instruksi biner dari masing-masing proses secara bergantian. Jadi kesalahan yang terjadi merupakan kesalahan run-time error dan tidak selalu dapat diulangi dan ditelusuri pada saat testing kode program. Jadi dalam kasus fungsi transfer di atas race condition terjadi karena proses mengakses dan mengubah sumber daya yang sama (nilai balance yang sama) tanpa saling berkoordinasi satu sama lain ataupun dengan sistem operasi, sehingga prosesor menjadwal ke dua proses bergantian secara bebas.

    Apa yang diperlukan untuk mengatasi kondisi race condition seperti kasus fungsi transfer di atas? Solusinya adalah menerapkan bentuk sin- kronisasi pada bagian kode yang melakukan pengaksesan atau peng- ubahan ke sumber daya yang digunakan bersama, variabel balance. Bagian kode dari program yang butuh diproteksi dengan mekanisme sinkronisasi ini disebut dengan critical section.

    Mengapa disebut sinkronisasi? Sinkronisasi berkaitan dengan pengaturan urutan eksekusi proses-proses yang terkait. Pada kasus transfer di atas, proses-proses yang melakukan fungsi transfer pada nilai balance yang sama, dijadwal oleh prosesor secara asinkron atau saling bebas satu sama lain. Artinya dari sudut pandang sistem operasi maupun pengguna, kedua proses berjalan secara asinkron seperti pada Gambar 4.11 (a).

    Pada Gambar 4.11, terdapat dua aktivitas yang berjalan secara, asinkron yaitu X dan Y. Yang merupakan critical section pada masing-masing aktivitas adalah aktivitas 2 dari proses Y dan aktivitas 3 dari proses X. Karena kedua aktivitas ini memanipulasi sumber daya B yang sama maka race condition terjadi.

    Untuk mengatasi hal ini maka urutan eksekusi aktivitas 2 dari Y dan aktivitas 3 dari X harus dibuat menjadi sinkron, yaitu salah satu aktivitas harus selesai dahulu baru aktivitas lainnya dapat dimulai. Sebagainya contoh, pada Gambar 4.11 (b), mekanisme sinkronisasi mengatur sedemikian rupa aktivitas 2 dari Y berjalan sampai selesai, baru aktivitas 3 dari X dapat dimulai. Mekanisme sinkronisasi seperti ini yang memastikan hanya satu proses yang yang berhak memanipulasi suatu sumber daya pada suatu waktu disebut juga dengan mutual exclusive atau disingkat mutex.


(a) Operasi asinkron


(b) Operasi sinkron

Gambar 4.11 Mekanisme Sinkronisasi



    Jadi, sinkronisasi merupakan mekanisme untuk memastikan operasi berjalan secara sinkron pada proses-proses konkuren yang saling meme- ngaruhi sehingga terjamin kelangsungan operasinya serta keabsahan status sumber daya yang dimanipulasi bersama. Contoh kasus fungsi transfer hanyalah merupakan salah satu kasus konkurensi yang mem- butuhkan mekanisme sinkronisasi. Solusi mutex yang dibahas di atas juga merupakan salah satu dari beragam bentuk sinkronisasi yang tersedia. Pada subbab masalah-masalah klasik pada sinkronisasi akan dibahas lebih banyak lagi kasus-kasus konkurensi beserta bentuk sinkronisasi yang cocok untuk mengatasinya.


4.4.2 IMPLEMENTASI SINKRONISASI


    Setelah mengerti mengapa diperlukan sinkronisasi maka hal yang se- lanjutnya perlu dipertanyakan adalah bagaimana sinkronisasi itu diimple- mentasikan? Implementasi sinkronisasi terkait dengan bagian kode proses yang disebut critical section. Mekanisme sinkronisasi bertugas mengoor- dinasi eksekusi critical section dari proses-proses yang terlibat. Pada dasarnya critical section berisi kode yang mengakses sumber daya, yang juga diakses ataupun disediakan oleh proses lain pada saat yang sama.

    Secara umum, mekanisme sinkronisasi memastikan operasi terhadap sumber daya tersebut terjadi secara mutual exclusive, yaitu setiap saat hanya diijinkan satu proses yang dapat mengakses dan memanipulasi sumber daya tersebut. Namun jika suatu sumber daya mengizinkan untuk diakses secara konkuren oleh N proses maka sinkronisasi bertugas memastikan pada suatu waktu, maksimal hanya sejumlah N proses yang dapat mengakses sumber daya tersebut.

    Implementasi sinkrosisasi proses umumnya harus memenuhi beberapa persyaratan di bawah ini.


1. Mutual Exclusion


Ketika suatu proses memasuki eksekusi kode critical section-nya maka tidak boleh ada proses lain yang juga memasuki critical section yang terkait. Sifat ini terutama benar untuk sumber daya yang pengaksesannya bersifat mutual exclusive. Sifat ini dapat didefinisikan ulang untuk sumber daya yang dapat diakses konkuren oleh sejumlah N proses.


2. Progress


Yaitu ketika ada proses yang hendak memasuki critical sectionmya dan pada saat itu tidak ada proses lain yang sedang melakukan critical section, permintaan untuk masuk ke critical section-nya haruslah dipenuhi


3. Bounded Waiting


Haruslah ada batasan tentang berapa kali proses lain boleh menyalib suatu proses yang telah lebih dahulu meminta ijin untuk memasuki critical section-nya.


Pada umumnya implementasi sinkronisasi harus dilakukan pada tiga bagian lapisan sistem komputer, yaitu aplikasi pengguna, perangkat keras, dan sistem operasi.


Sinkronisasi Aplikasi Pengguna


Pada program aplikasi yang menerapkan sinkronisasi, ada kode tambahan yang harus ditambahkan sebagai implementasi dari mekanisme sinkroni- sasi. Kode tambahan ini disebut entry section dan exit section dan harus diletakkan mengapit bagian kode yang diidentifikasi sebagai critical section seperti ditunjukkan pada gambar 4.12.


Do


{


Contoh Sinkronisasi pada 2 proses Proses P1


Entry Section


Critiont Section


Exit Section


Remainder Section


Entry While giliran a 0 do no operasi


Exit gran 1


Proses P2


Entry: While gasm #1 do no operas


Exit giliran0


Gambar 4.12. Sinkronasi pada Aplikasi (Software)


    Entry section berfungsi untuk memastikan mutual exclusive. Bagian ini menguji apakah proses dapat melanjutkan ke critical sectiomya. Misalnya pada kasus Gambar 4.12, terdapat dua proses P1 dan P2 yang hendak melakukan critical section-nya masing-masing. Pengaturan eksekusi critical section menggunakan variable kontrol giliran, yaitu nilai giliran-0 berarti Pl diijinkan untuk eksekusi critical section-nya, dan nilai giliran=1 berarti P2 yang diijinkan untuk eksekusi critical sectionya.

    Entry section pada proses P1 akan menguji nilai giliran terus menerus dan selama nilai giliran tidak sama dengan O maka pengujian akan diulang terus. Hal yang mirip terjadi pada proses P2, tetapi proses P2 akan melakukan pengujian nilai giliran terus menerus selama nilai giliran tidak sama dengan 1. Pengujian yang terus menerus atau looping ini disebut dengan busy waiting dan tetap menggunakan siklus eksekusi prosesor.

    Misalnya nilai giliran-0, maka P1 yang akan diijinkan terlebih dahulu mengeksekusi critical section-nya. Jika P1 sudah selesai mengeksekusi critical section-nya maka kode eksekusi P1 akan mengalir ke bagian exit section.

    Fungsi bagian exit section adalah untuk memastikan sifat progress dari mekanisme sinkronisasi, yaitu jika P1 sudah selesai mengeksekusi critical section-nya maka P1 tidak boleh menghalangi proses lainnya untuk melanjutkan ke critical section-nya. Oleh sebab itu, bagian exit section Pl mengubah nilai giliran=1, artinya P1 mempersilakan P2 untuk melanjutkan critical section-nya jika P2 sedang menunggu di bagian entry section-nya sendiri.


Sinkronisasi Perangkat Keras


    Kode program pada bagian entry section dan exit section pada contoh sebelumnya memiliki masalah serius, yaitu hanya dapat menangani 2 proses. Untuk proses yang lebih banyak, berarti butuh ditentukan nilai- nilai giliran untuk tiap-tiap proses. Hal seperti ini akan sangat kompleks jika proses yang butuh disinkronisasi berjumlah banyak. Hal demikian dapat disederhanakan dengan memakai variabel yang menyerupai fungsi kunci yang hanya bernilai benar (true) dan salah (false). Konstruksi entry section dan exit section menjadi seperti Gambar 4.13



Do
{
while (TestAndSet(lock));
    critical action
lock = false;
    remainder section
}

 


Gambar 4.13 Sinkronisasi Hardware


    Entry section proses bertugas menguji nilai kunci (lock). Jika lock tertutup atau lock-true maka proses tersebut harus melakukan busy waiting. Jika lock terbuka atau lock=false maka proses dapat melanjutkan eksekusi ke bagian critical section sekaligus mengubah nilai lock-true. Di bagian exit section, proses mengubah nilai lock-false sehingga proses lain yang menunggu terbukanya lock tersebut dapat melanjutkan eksekusi ke bagian critical section mereka juga.

    Namun skenario ini membawa masalah baru pada bagian entry section. Fungsi pengujian nilai kunci (test) dan mengubah nilai kunci menjadi tertutup (set) haruslah dilakukan secara atomik dan tidak boleh disela oleh entry section proses lain. Dengan kata lain, entry section-nya juga butuh disinkronisasi! Untuk mengatasi hal ini secara tuntas, tidak ada cara lain selain mengimplementasi instruksi test dan set menjadi suatu instruksi tunggal, atomik, pada tingkat perangkat keras. Pada kebanyakan arsitektur prosesor terdapat fungsi yang demikian. Sebagai contoh adalah instruksi Test and Set (ts) pada IBM 370 dan instruksi Exchange (xchg) pada Intel 80x86. Intruksi tersebut di atas bersifat atomik, yaitu tidak dapat disela atau diinterupsi oleh instruksi lain.



Sinkronisasi Sistem Operasi


    Dengan skenario sebelumnya, masih menyisakan satu persoalan yaitu tetap terjadinya busy waiting pada bagian entry section karena ada kontruksi looping. Permasalahannya adalah proses yang busy waiting tetap mengonsumsi siklus prosesor untuk pengujian lock. Aktivitas yang tidak menghasilkan output nyata ini tentunya mengurangi keluaran (throughput) bagi proses-proses lainnya. Selain itu, jika proses yang busy waiting memiliki prioritas lebih tinggi dibanding proses lain maka kondisi ini akan menghalangi eksekusi proses-proses lainnya. Kondisi ini merupakan suatu deadlock dan dikenal dengan priority inversion problem.

    Untuk mengoptimalkan pemakaian prosesor maka sinkronisasi mem- butuhkan campur tangan rutin sistem operasi untuk meniadakan terjadinya busy waiting pada bagian entry section dari suatu proses. Hal ini dapat dilakukan dengan menyediakan fungsi atau rutin sistem operasi yang dapat dipanggil pada bagian entry section dan exit section. Model sinkronisasi menggunakan rutin sistem operasi dapat ditunjukkan pada Gambar 4.14.


Do
{
wait (lock):
critical section
signal (lock):
remainder section
}


Gambar 4.14 Sinkronisasi dengan Primitif Sistem Operasi


           Baik fungsi wait(lock) maupun signal(lock) merupakan rutin yang disediakan oleh sistem operasi. Mengapa harus rutin sistem operasi? Ini dikarenakan kita membutuhkan kemampuan untuk mengatur siklus atau status dari proses yang terlibat. Yaitu mengubah suatu proses berstatus running menjadi blocked ataupun sebaliknya.

    Fungsi wait diletakkan pada bagian entry section, sedangkan fungsi signal diletakkan pada bagian exit section. Fungsi wait berfungsi untuk menguji status lock. Jika lock terbuka maka proses akan melanjutkan eksekusinya ke critical section sekaliguskan mengunci lock. Namun jika lock terkunci maka fungsi wait akan membuat status proses bersangkutan menjadi blocked dan dimasukkan dalam antrian lock bersangkutan. Setelah suatu proses menyelesaikan bagian critical section maka proses akan melanjut- kan eksekusi ke bagian exit section dengan memanggil fungsi signal Fungsi signal akan membebaskan lock, dan sekaligus membangunkan, operasi wake-up, semua proses yang menunggu di antrian lock tersebut.

    Fungsi sistem operasi dalam rutin wait dan signal ibarat tugas seorang resepsionis pada praktik seorang dokter. Jika dokter sedang memeriksa seorang pasien maka semua pengunjung yang datang harus melapor ke resepsionis lebih dahulu. Daripada mereka harus mengecek terus ke resespsionis maka resepsionis akan mempersilakan mereka menunggu di ruang tunggu. Seandainya pasien yang diperiksa dokter sudah selesai, maka resepsionis yang akan memanggil pasien berikutnya. Dengan demikian pengunjung tidak perlu terus menerus mengecek ke resepsionis. Resepsionis cukup memberitahu ke pasien-pasien lainnya yang sedang menunggu setiap kali pemeriksaan seorang pasien telah selesai.

Contoh kasus fungsi transfer uang yang dijelaskan pada bagian sebelum- nya hanyalah salah satu contoh kasus konkurensi yang membutuhkan mekanisme sinkronisasi. Pada kasus transfer uang, digunakan bentuk sinkronisasi yang disebut dengan mutual exclusive (mutex) yang me mastikan hanya satu proses yang diijinkan masuk ke critical section pada setiap saat.


Mutex merupakan salah satu bentuk khusus dari semaphor dan dikenal dengan istilah binary semaphore yang merupakan mekanisme sin kronisasi yang lebih umum. Jika mutex hanya mengijinkan satu (n=1)


proses memasuki critical section-nya maka semaphore mengijinkan sejumlah proses (n>1) untuk memasuki critical section secara bersamaan. Selain semaphore dan mutex, masih terdapat mekanisme lain seperti monitor. Mekanisme monitor jauh lebih kompleks dan tidak akan dibahas dalam buku ini.


Di bawah ini akan dibahas sejumlah masalah klasik konkurensi yang membutuhkan mekanisme sinkronisasi: Bounded Buffer (Produser- Consumer), Dining Philosopher, Readers and Writers, serta Sleeping Barber. Masalah-masalah konkurensi di atas lebih kompleks dibanding- kan dengan kasus transfer uang dan membutuhkan teknik sinkronisasi yang lebih kompleks dan berbeda satu sama lainnya.


4.5.1 MASALAH BOUNDED-BUFFER (PRODUCER-CONSUMERS)


Pada kasus Bounded-Buffer, diasumsikan terdapat suatu buffer yang memiliki kapasitas terbatas sejumlah n. Produser mengisi buffer, sedangkan Consumer memindahkan atau menghapus isi buffer. Masalah timbul pada produser jika buffer sudah penuh sehingga tidak dapat diisi lebih lanjut. Sementara bagi consumer, masalah muncul jika buffer menjadi kosong sehingga tidak ada item yang dapat dipindahkan lebih lanjut. Selain itu saat salah satu pihak melakukan operasinya maka pihak lainnya tidak boleh melakukan operasinya. Atau dengan kata lain operasi produser dan operasi consumer haruslah mutual exclusive (mutex).


Salah satu bentuk solusi terhadap masalah konkurensi ini adalah menggunakan 3 semaphore yaitu full, empty, dan mutex. Konstruksi sinkronisasi menggunakan semaphore ini dapat dilihat pada Gambar 4.15. Nilai full menandakan jumlah slot buffer yang terisi, nilai empty menunjukkan sisa slot buffer yang masih kosong atau masih dapat diisi, sedangkan mutex menandakan boleh tidaknya suatu proses, baik producer maupun consumer, mengakses buffer.


Nilai awal full adalah 0, yang artinya buffer masih kosong, dan nilai awal empty adalah N, yaitu kapasitas slot buffer, dan nilai awal mutex adalah 1. Instruksi wait(semaphore) akan menurunkan nilai semaphore. Namun jika nilai semaphore sudah 0 maka proses bersangkutan akan beralih status menjadi blocked dan menunggu sampai terjadi eksekusi instruksi signal(semaphore) oleh proses lain. Instruksi signal(semaphore) sebaliknya akan menaikkan nilai semaphore dan membangunkan proses blocked yang sedang menunggu semaphore bersangkutan.


Untuk proses produser, setelah item diproduksi maka perintah wair (empty) dilakukan untuk memastikan masih terdapat slot kosong pada buffer. Kalau slot sedang kosong, maka proses produser akan beralih status menjadi blocked sampai tersedia slot kosong pada buffer. Jika terdapat slot kosong pada buffer maka instruksi wait(empty) akan menyebabkan nilai empty berkurang satu dan menandakan jumlah slot kosong pada buffer berkurang satu. Selanjutnya proses produser melakukan instruksi wait(mutex) untuk memastikan tidak ada proses lain. yaitu consumer, yang sedang mengakses buffer.


Jika dua kondisi di atas terpenuhi maka produser akan melakukan critical section-nya, yaitu memasukkan item yang diproduksi ke dalam buffer. Setelah itu, produser akan membebaskan mutex dengan instruksi signal(mutex) sehingga proses lain mendapat giliran untuk mengakses buffer. Proses produser selanjutnya melakukan instruksi signal(full) yang akan menaikkan satu nilai full dan menandakan slot buffer yang terisi bertambah satu.


Pada sisi proses consumer, langkah pertama wait(full) berfungsi memasti- kan terdapat slot terisi atau item yang dapat dikonsumsi. Nilai full-0 menandakan tidak item dalam buffer, sehingga proses consumer akan beralih status menjadi blocked dan menunggu sampai buffer terisi item baru. Jika buffer memiliki item maka instruksi selanjutnya yaitu wait(mutex) memastikan tidak ada proses lain yang sedang mengakses buffer.


Jika kedua kondisi di atas terpenuhi maka proses akan mengonsumsi item pada buffer. Setelah itu, proses akan membebaskan kembali mutex dengan perintah signal(mutex) dan menaikkan nilai jumlah slot buffer yang kosong dengan instruksi signal(empty).



Data yang dipakal bersama


type rem


var buffer =


full, empty, mutex: semaphore, fut = 0; empty n. mutex -1.


Proses Produser


repeat


membuat item


warmutex


menyisipkan itam ke buffer


signal mutex)


signal ful


until falso


Proses Consumer


repeat


wait(full) wait(mutex) ambil dan hapus satu item dari buffer signal(mutex) signal(empty);


until false,


Gambar 4.15 Solusi sinkronsiasi untuk masalah producer consumer


Selain menggunakan semaphore, masalah producer dan consumer dapat juga diselesaikan dengan menggunakan monitor dan message passing Kontruksi sinkronisasi dengan menggunakan monitor dan message passing dapat dilihat pada Tanembaum, A.S. (2001).


Manajemen Proses


117


4.5.2 MASALAH READERS AND WRITERS


Sebuah data, baik berupa berkas maupun rekaman di basis data, terkadang digunakan bersama oleh sejumlah proses secara bersamaan. Beberapa proses mungkin melakukan operasi baca (read), sedangkan yang lain melakukan operasi tulis (write) baik berupa penyisipan data baru ataupun modifikasi terhadap data lama. Umumnya jika semua proses yang berjalan bersamaan adalah operasi baca, tidak ada masalah yang muncul. Namun ika terdapat satu saja proses yang melakukan operasi tulis maka masalah dapat muncul. Kasus konkurensi ini disebut dengan masalah readers and writers.


Untuk mencegah hal tersebut maka proses write harus mendapatkan hak akses eksklusif terhadap data yang digunakan bersama. Artinya sebelum proses write melakukan critical section-nya, harus dipastikan seluruh proses read sudah selesai dan ketika proses write sedang mengeksekusi critical sectiomya, tidak ada proses read yang diijinkan untuk beroperasi. Solusi sinkronsisasi untuk masalah readers and writers ini ditunjukkan pada Gambar 4.16.


Dalam solusi ini digunakan dua semaphore, lebih tepatnya adalah mutex, yaitu reader Mutex dan dataMutex. Selain itu, terdapat counter readcount untuk mencatat proses reader yang aktif. Variabel reader Mutex diguna- kan untuk mensinkronisasikan pembaharuan nilai readcount, sedangkan data Mutex digunakan untuk mensinkronisasi akses ke data oleh proses reader pertama dan proses writer.


Perhatikan, jika proses reader terjadi lebih dahulu dibanding proses writer maka akses ke data akan mulai terkunci oleh instruksi wait dari proses reader yang pertama, dan hanya akan dibebaskan oleh instruksi signal dari proses reader yang terakhir yang selesai. Ini berarti jika ada proses reader yang masih aktif maka reader yang masuk berikutnya dapat langsung membaca, bahkan jika ada proses writer yang sedang menunggu. Proses writer hanya dapat melanjutkan eksekusinya jika seluruh proses reader sudah selesai. Disisi lain, jika proses writer terjadi lebih dahulu dibanding proses reader maka seluruh proses reader yang terjadi sesu dahnya harus menunggu sampai proses writer menyelesaikan eksekusi- nya.


118


Sistem Operasi


Data yang dipakai bersama


VirenderMutax data Mutex: Semaphore


readcounts antige


reador Muter 1 dateMutext, readcount=0,


Proses Writer


wait data fotent


operasi wrze


aignal (dala Mit Proses Reader waill readork readcount


Toreadcount=1 then hata Mutex);


operasiroad


waitt readerMutex


readcount readcount-1, if readcount = 0 then signal data Mutex); signal reader Mutex)


Gambar 4.16 Solusi sinkronisasi masalah readers and writers


Solusi sinkronisasi yang dijelaskan memiliki kelemahan. Jika proses reader terjadi terus menerus secara konstan maka dapat terjadi proses writer yang sedang menunggu tidak akan pernah mendapat giliran sama sekali. Kondisi ini ini disebut dengan kondisi starvation bagi proses writer. Salah satu solusi yang dianjurkan adalah, jika terdapat proses writer yang sedang menunggu maka proses reader yang mencoba masuk harus menunggu dan tidak boleh mendahului proses writer yang terlebih dahulu menunggu. Konsekuensinya adalah berkurangnya tingkat konkurensi yang dapat dicapai dan mengurangi unjuk kerja sistem.



Manajemen Proses


119


4.5.3 MASALAH DINING PHILOSOPHER


Masalah konkurensi klasik ini pertama dikemukakan oleh Dijkstra pada tahun 1965. Kondisi ini dilukiskan pada Gambar 4.17. Misalnya ada 5 filsuf yang menghabiskan waktunya untuk berpikir dan makan. Mereka duduk bersama mengelilingi satu meja makan dengan lima buah piring yang masing-masing dibatasi dengan sumpit. Di tengah terdapat satu bakul nasi. Ketika sedang berpikir filsuf akan diam saja. Namun ketika sedang lapar maka ia dapat mengambil kedua sumpit di sampingnya. Mungkin ia hanya mengambil satu sumpit. Tetapi tentu saja ia tidak akan mengambil sumpit yang sudah dipegang oleh yang lain. Ketika lapar berat, ia akan mengambil kedua sumpit dan tidak akan melepaskan selama makan. Baru setelah selesai makan, ia akan melepaskan sumpit dan mulai berpikir kembali.


Gambar 4.17 Masalah Dining-philosopher


Dining-philosopher merupakan masalah klasik konkurensi dan secara sederhana menunjukkan masalah yang muncul ketika terjadi peng- alokasian beberapa sumber daya, resource, untuk beberapa proses yang dapat berakibat deadlock ataupun starvation. Untuk masalah deadlock akan dibahas secara khusus pada bagian terakhir dari bab ini.


120


Sistem Operasi


Salah satu penyelesaian sederhana untuk masalah dining-philosopher adalah dengan menggunakan satu sempahore atau tepatnya mutex pada setiap sumpit. Setiap sumpit atau mutex dan juga filsuf akan diindeks dari O sampai 4. Filsuf (1) yang ingin makan akan mencoba mengeksekusi instruksi wait terhadap mutex sumpit kiri, yaitu chopstick[i] dan mutex sumpit kanannya, yaitu chopstick[i+1]. Jika sudah selesai makan, proses filsuf akan melakukan instruksi signal untuk membebaskan kedua sumpit tersebut, yaitu signal(chopstick[i]) dan signal(chopstick[i+1]). Secara lengkap, langkah sinkronisasi dapat dideskripsi pada Gambar 4.18.


Philosopher


repeat


wail(chopstick mod 5)


agra (chopstick):


Signal chopstick mod 51);


think


until falso:


Gambar 4.18 Solusi sinkronisasi pada masalah dining philosopher


Meskipun cara ini menjamin tidak akan ada dua filsuf yang berdekatan makan secara bersamaan, tetapi cara ini masih memungkinkan terjadinya deadlock. Misalnya kelima filsuf lapar secara bersamaan dan bersamaan pula berhasil mengambil sumpit di sisi kirinya maka ketika akan mengambil sumpit di sisi kanannya akan terjadi deadlock. Beberapa perbaikan yang dapat dilakukan untuk mengatasi deadlock dan menghindarkan timbulnya salah satu filsuf mati kelaparan adalah:


Manajemen Proses


121


1. Membolehkan maksimal 4 filsuf yang secara bersamaan duduk di meja makan.


2. Membolehkan filsuf untuk mengambil sumpit jika kedua buah sumpit tersedia, yaitu menjadi instruksi wait(chopstick[i]) dan wait(chopstick [i+1]) sebagai critical section yang harus disinkronisasi dengan suatu mutex baru.


3. Menggunakan penyelesaian asimetris. Filsuf ganjil mengambil sumpit di kirinya baru kemudian sumpit yang kanan. Sementara filsuf genap dengan cara sebaliknya, yaitu mengambil sumpit kanan dahulu baru kemudian mengambil sumpit kiri.


4.5.4 MASALAH SLEEPING BARBER


Masalah konkurensi klasik lainnya dianalogikan kondisinya seperti di tempat potong rambut, yang hanya memiliki satu kursi potong dan memiliki sejumlah n kursi tunggu. Jika tidak ada pelanggan maka tukang potong rambut (barber) akan tidur di kursi potong. Jika ada pelangan yang masuk maka si tukang potong harus dibangunkan. Jika pelanggan lainnya datang, pelanggan tersebut akan melihat apakah ada kursi tunggu yang tersedia dan menunggu disana. Jika ternyata tidak ada kursi tunggu yang kosong, pelanggan tersebut meninggalkan tempat tersebut.


Masalahnya adalah bagaimana mengatur agar tidak terjadi race condition untuk proses tukang potong dan proses pelanggan. Kondisi seperti ini umumnya terjadi pada kasus antrian, seperti hel pada esk yang dapat melayani sejumlah m panggilan lewat sejumlah n komputer secara simultan, di mana sering terjadi m > n. Salah satu solusinya adalah menggunakan 3 buah semaphore.


1. customers untuk menghitung jumlah pelanggan yang menunggu, tidak termasuk pelanggan yang sedang dipotong rambutnya,


2. barbers, untuk menghitung jumlah tukang potong yang tersedia atau yang sedang tidur, dimana dalam kasus ini hanya ada satu tukang potong sehingga cukup menggunakan mutex atau binary semaphore.


3. waitingmutex, untuk mensinkronisasi pengubahan terhadap nilai variabel waiting, yang digunakan untuk mencatat jumlah pelangan


122


Sistem Operasi


yang sedang menunggu. Perhatikan, sekalipun semaphore customers secara implisit memiliki nilai yang menunjukkan jumlah pelanggan yang sedang menunggu, pengubahan nilainya hanya dapat dilakukan lewat operasi wait dan signal. Untuk kebutuhan program, diperlukan variabel lain, yaitu waiting untuk mencatat jumlah pelanggan yang menunggu.


Secara lengkap, langkah-langkah sinkronisasi pada proses barber maupun customer ditunjukkan oleh Gambar 4.19.


Data yang dipakai bersama


var kursi Tunggu


waiting mteger customera, barbers, waitingmulex, semaphore customers, burturs 0; waitingimutex=1; waiting:=0:


Prosos Barber wall(customers): midur jika tidak ada pelanggan watt waitinginkite ki, akses te antrian tunggu waiting waiting-1: Miurangi jumlah antian signal barbersy laekarang berber siap melayani signal(warningmutex); //lepaskan akses intran operasi pemotongan rambut


Proses Customers


aignal(waltingmutex), Ankses antrian waiting skaira Tunggul fika ada kurst kosong wailing waiting +1: //tambah antrian signal(customers), nambah jumlah anthan signal(writingmutex); Repas akses antrian wait(barbers); //menunggu tukang potong dilayani potong rambut


else


signal waitingmulex)}


Gambar 4.19 Solusi sinkronisasi pada masalah sleeping barber