Fendy Chandra – 1601221420
Di pertemuan ini, kita belajar yang namanya concurrency. Apa itu concurrency? Simpelnya, concurrency bisa diartiin sebagai komunikasi antar beberapa process yang saling berbagi resources yang sama. Di dalam komunikasi ini, ada sinkronisasi dari beberapa proses yang sama-sama memakai resource tertentu. Nah supaya proses-proses ini dapat berjalan dengan baik, perlu dilakuin yang namanya alokasi processor time. Nah contoh penerapan concurrency ini bisa dalam multiprogramming (penggunaan beberapa aplikasi pada saat yang sama), dalam aplikasi terstruktur (structured application, aplikasi ini disusun dari berbagai perintah yang concurrent), dan di dalam struktur sistem operasi (karena OS itu adalah sekumpulan proses/thread).
Nah walopun sebenernya concurrency ini adalah metode yang bagus buat meningkatkan efisiensi komputer, tapi ada beberapa permasalahan yang sering muncul kalo menerapkan concurrency:
- Sharing global resources
- Pengelolaan alokasi resources
- Kesalahan-kesalahan yang terjadi sewaktu programming susah ditemukan (di-debug) setelah dieksekusi.
Permasalahan tentang concurrency bisa diliat di contoh codingan ini:
void echo (
{
chin = getchar();
chout = chin;
putchar(chout);
}
Proses 1 | Proses 2 |
. | . |
in = getchar(); | . |
. | in = getchar(); |
chout = chin; | chout = chin; |
putchar(chout) | . |
. | putchar(chout) |
Kalo kita liat contoh diatas, bisa terjadi masalah buat proses 1 kalo nilai yang ditampung sama in di proses 1 ke-overwrite sama in di proses 2, sehingga hasilnya bisa ga reliable. Untuk mengatasi masalah-masalah semacem ini, ada beberapa cara yang bisa kita lakuin (bakal dibahas selanjutnya).
Nah, berhubungan sama concurrency ini, O/S punya beberapa concern, diantaranya:
- Mentrack proses-proses yang sedang aktif
- Mengalokasi dan mendealokasi resource-resource semacem processor time, memory, file, dan I/O devices
- Melindungi data dan resource
- Hasil dari proses harus independen terhadap kecepatan eksekusi dari proses-proses lain yang concurrent.
Nah, dalam konkurensi ini, ga jarang terjadi yang namanya kompetisi antar proses yang konkuren. Nah dalam kompetisi ini ada istilah mutual exclusion (berkaitan sama critical sections, yaitu cuma ada 1 program yang boleh berada dalam critical sections, contohnya Cuma ada 1 proses yang boleh ngasih perintah ke printer dalam 1 waktu). Masalahnya akibat mutual exclusion ini bisa aja terjadi yang namanya deadlock dan starvation. Deadlock maksudnya ada 2 proses yang musti tunggu-tungguan buat melakukan 1 eksekusi tertentu. Karena saling tunggu, yang ada akhirnya malah kedua-duanya ga ada yang jalan. Kalo starvation itu adalah situasi dimana 1 proses nunggu terlalu lama buat memakai 1 resource/eksekusi tertentu.
Selain kompetisi, ada juga yang namanya kooperasi. Nah kooperasi ini dibagi jadi 2 macem:
- By sharing, nah dalam kooperasi ini, writing harus dilakuin secara mutually exclusive. Supaya integritas datanya terjaga, maka perlu dipake yang namanya critical sections.
- By communication, nah dalam kooperasi ini, pesan-pesan yang ada dioper antar 1 proses ke proses yang lain (jadi tidak harus ada mutual exclusion). Karena itu, dalam kooperasi ini ada kemungkinan terjadinya deadlock dan starvation).
Nah tadi kan udah disinggung sedikit soal mutual exclusion. Sekarang bakal dijelasin secara lebih lengkap tentang mutual exclusion. Jadi, mutual exclusion itu adalah Suatu metode yang memungkinkan supaya Cuma ada 1 proses dalam 1 waktu yang berhak berada dalam critical section dari suatu resource. Sebuah proses yang berhenti di non-critical section dari suatu proses harus melakukannya tanpa mengganggu proses-proses yang lain. Karena itu, dalam mutual exclusion ga ada yang namanya deadlock atopun starvation. Dengan metode ini, suatu proses ga boleh terhambat dalam memasuki critical section dari suatu resource kalo critical section itu lagi kosong, tapi setelah ada didalemnya, proses itu terbatas berada disana dalam satu waktu tertentu.
Nah supaya bisa mencapai mutual exclusion ini, ada beberapa cara yang bisa dilakukan:
- Dengan men-disable interrupts.
Umumnya, suatu proses berjalan sampai dia memanggil suatu layanan OS ato sampai diinterupsi. Dengan metode ini, kita mencegah munculnya interupsi, sehingga bisa menjamin mutual exclusion. Selain itu, metode ini juga dibatasi kemampuannya dalam meng-interleave program. Tetapi jika kita menggunakan multiprocessing, men-disable interrupt di 1 prosesor ga bakal menjamin mutual exclusion.
- Memakai lock variable
Dengan metode ini, kita menggunakan suatu variable yang berperan sebagai kunci (lock). Variable ini diinisialisasi dengan nilai 0. Jika lock = 0, maka proses boleh memasuki critical section, lalu nilai lock diubah menjadi 1. Setelah proses keluar, maka lock akan kembali diberi nilai 0. Jika ada proses yang ingin masuk tapi nilai lock = 1, maka proses itu harus menunggu samapi lock = 0. Permasalahan yang bisa timbul dari metode ini adalah race condition, dimana 2 proses mencapai critical section pada waktu yang hampir bersamaan.
- Menggunakan strict alteration
- Menggunakan Peterson’s solution
- Memakai instruksi TSL
Nah selain memakai metode mutual exclusion, permasalahan-permasalahan concurrency bisa dicegah dengan memakai semaphore. Semaphore adalah suatu variable khusus yang digunakan untuk signaling. Jika sebuah proses menunggu sinyal, maka proses itu akan di-suspend sampai sinyalnya terkirim. Wait dan operasi-operasi sinyal ini tidak bisa diinterupsi. Untuk menampung proses-proses yang menunggu semaphore ini kita perlu memakai queue.
Semaphore sendiri adalah variable khusus yang memiliki nilai integer:
- Semaphore ini bisa diinisialisasi dengan nilai negative.
- Operasi wait akan men-decrement nilai semaphore
- Operasi signal akan meng-increment nilai semaphore.
Nah berkaitan sama concurrency ini ada permasalahan yang namanya Producer-Consumer’s problem. Nah dalam permasalahan ini, ada 1 atau lebih producer yang men-generate dan menemoatkan data-data ini kedalam buffer, sedangkan ada 1 consumer yang mengambil item-item keluar dari buffer sebanyak 1 di setiap waktu. Permasalahannya adalah hanya ada 1 consumer/producer yang boleh mengakses buffer dalam satu waktu.
Selain producer-consumer, ada juga permasalahan yang namanya dining philosopher’s problem dan readers’ writer problem. Kalo dalam masalah ini, reader dalam jumlah berapapun boleh membaca file secara simultan, tetapi hanya ada 1 writer yang boleh menulis file tersebut dalam 1 waktu. Ketika writer sedang menulis file, tidak boleh ada reader yang boleh membaca file.
Berikut ini adalah solusi dari producer-consumer problem:
Berikut ini adalah salah satu solusi yang dapat digunakan untuk mengatasi Reader’s Writer Problem:
Solusi lainnya dari permasalahan ini jika menggunakan semaphore adalah sebagai berikut:
Kalo yang ini adalah solusi Dining Philosopher’s Problem:
Nah kalodalem prakteknya, kita bisa menggunakan keyword mutex lock dan mutex unlock buat menjalankan concurrency. Nah dalam mutex ini, kita perlu memakai yang namanya pthread kayak dibawah ini:
Nah kalo kita make pthread buat mengatasi masalah producer-consumer kita bisa juga, contohnya kayak dibawah ini:
Selain itu, dipertemuan minggu kemaren kita juga ngebahas tentang monitor, yaitu suatu konstruksi bahasa pemrograman yang mendukung akses terkontrol ke shared data. Jadi dengan adanya monitor, compiler menambahkan sinkronisasi secara otomatis dan di-enforce pada saat runtime. Dalam monitor, Cuma boleh ada 1 proses yang berada didalamnya dalam 1 waktu (hal ini dikarenakan setiap procedurenya adalah bagian dari critical section).
Jadi, monitor ini mendukung mutual exclusion, karena Cuma ada 1 proses yang bisa mengeksekusi didalam monitor pada 1 waktu, dan proses-proses lain yang ingin memakai monitor tersebut harus meunggu sampai proses yang ada didalamnya selesai mengeksekusi. Saat berada didalam monitor, sebuah proses bisa saja menemukan dirinya tidak dapat berlanjut, hal ini salah satunya disebabkan karena didalam monitor terdapat conditional variables yang bisa diakses dengan fungsi wait dan signal.
Nah untuk memungkinkan sebuah proses untuk menunggu didalam monitor, kita perlu membuat sebuah variable condition, misalnya condition x;
Nah variable ini Cuma bisa diakses dengan 2 operasi/fungsi, yaitu wait dan signal.
- Wait (x) berarti proses yang meng-invoke operasi ini (x) akan di-suspend sampai proses lain meng-invoke.
- Signal (x) akan melanjutkan tepat 1 proses yang sudah di-suspend. Jika tidak ada proses yang di-suspend, maka operasi ini tidak punya efek apapun.
Terakhir, di pertemuan kemaren kita juga belajar tentang message passing. Message passing adalah suatu cara untuk mengkomunikasikan operasi dari 1 proses ke proses lainnya dengan operasi send dan receive. Receiver bisa menspesifikasikan apapun, memilih untuk mem-blok ataupun tidak. Metode message passing ini bisa diterapkan dalam single-processing system, multi-processing system, dan distributed system. Metode ini tidak memerlukan shared address spaces.
Operasi send() dapat bersifat synchronous ataupun asynchronous. Synchronous send akan me-return setelah data dikirm dan memblok jika buffernya penuh, sedangkan asynchronous send akan me-return segera setelah I/O dimulai dan akan memblok jika buffer dianggap penuh.
Operasi receive() juga dapat bersifat synchronous ataupun asynchronous. Synchronous receive akan me-return jika ada pesan dan akan memblok jika tidak ada pesan, sedangkan asynchronous receive akan mereturn pesan pertama jika ada 1 pesan dan meretun indikasi jika tidak ada pesan.
Message passing juga bisa dilakukan secara indirect dengan menggunakan mailbox. Jadi, sebuah pesan akan dikirim ke suatu area tertentu yang diberi nama (mailbox). Proses-proses akan membaca pesan dari mailbox, jadi mailbox ini harus dibuat dan dikelola. Sender akan memblok jika mailboxnya sudah penuh. Keuntungan dari penggunaan mailbox adalah metode ini memungkinkan komunikasi many-to-many.
Dalam message passing, jika sebuah pesan dikirim balik ke sender berarti pesan aslinya sudah diterima dengan tepat. Pesan ini juga bisa dikirm secara piggy-back ke pesan lain baik secara implisit maupun eksplisit. Message passing juga bisa synchronous ataupun asynchronous dan positif ataupun negative.
Berikut ini adalah penggunaan message passing untuk menyelesaikan permasalahan producer-consumer :
Walopun metode ini keliatan bagus, tapi message passing juga punya beberapa masalah yang perlu dipertimbangkan:
- Scrambled messages (checksum)
- Lost messages (acknowledgements)
- Lost acknowledgements (sequence no.)
- Destination unreachable (down, terminates) -> karena mailbox penuh
- Naming
- Authentication
- Performance (copying, message building)
BINUS (www.binus.ac.id) | www.skyconnectiva.com