Proses-proses yang
konkuren adalah proses-proses
(lebih dari satu)
berada pada saat yang sama.
Proses-proses ini dapat sepenuhnya tak bergantung dengan yang
lainnya, tapi dapat
juga saling berinteraksi. Proses-proses yang
berinteraksi memerlukan sinkronisasi agar terkendali dengan baik.
Proses-proses yang
melakukan akses secara
konkuren pada data
yang digunakan bersama-sama menyebabkan data tidak konsisten
(inconsistence). Agar data konsisten
dibutuhkan mekanisme untuk menjamin eksekusi yang berurutan pada proses-proses
yang bekerja sama. Pada model shared memory untuk penyelesaian
permasalahan
bounded-buffer paling banyak menyimpan n
– 1 item pada buffer pada saat yang bersamaan.
Untuk mendapatkan solusi dimana
semua N buffer digunakan bukan
masalah yang sederhana.
Misalnya dilakukan modifikasi
kode producer- consumer dengan menambahkan variabel counter yang diinisialisasi 0 dan dinaikkan setiap satu item baru
ditambahkan ke buffer. Definisi
data yang digunakan bersama- sama
(shared data) adalah sebagai berikut :
#define BUFFER_SIZE 10 typedef struct {
. . .
} item;
item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int counter = 0;
Proses pada producer akan menambahkan satu nilai
variabel counter sebagai berikut :
item nextProduced;
while (1) {
while (counter == BUFFER_SIZE)
; /* do nothing */
buffer[in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
Sebaliknya juga proses
pada consumer akan menurunkan satu nilai variabel counter sebagai berikut :
item nextConsumed;
while (1) {
while (counter == 0)
; /* do nothing */
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
}
Pernyataan
counter++ dan counter--
harus dilakukan secara
atomik. Operasi atomik adalah operasi yang harus menyelesaikan seluruh
pernyataannya tanpa interupsi.
Pernyataan counter++ akan diimplementasikan dalam bahasa mesin sebagai
berikut :
register1 = counter
register1 = register1 + 1 counter = register1
Sedangkan
pernyataan counter-- akan
diimplementasikan dalam bahasa
mesin sebagai berikut :
register1 = counter register1 = register1 + 1 counter = register1
Apabila
baik producer dan
consumer mencoba mengubah
buffer secara konkuren, pernyataan
dalam bahasa mesin
diatas akan dilakukan
secara terpisah. Misalnya counter
diinisialisasi 5. Pernyataan yang
dijalankan adalah :
producer: register1 = counter (register1
= 5)
producer: register1 = register1 + 1 (register1 = 6) consumer: register2 = counter (register2 = 5) consumer: register2 = register2 – 1 (register2 = 4) producer:
counter = register1 (counter = 6)
consumer: counter = register2 (counter = 4)
Nilai counter
kemungkinan bernilai 4
atau 6, sedangkan
hasil yang benar seharusnya 5, hal ini yang dimaksud
dengan data yang tidak konsisten.
Situasi dimana beberapa
proses mengakses dan
memanipulasi data yang
digunakan bersama-sama secara
konkuren disebut dengan race condition.
Nilai akhir dari data yang digunakan bersama-sama tersebut tergantung
dari proses yang terakhir selesai.
Untuk mencegah race condition tersebut, proses yang konkuren harus
dilakukan sinkronisasi.