4 Minutes      July 16, 2012      Programming Programming/PHP

PHP Semaphore (Bagian 2)

Pada tulisan PHP Semaphore (Bagian 1), saya sudah menjelaskan sedikit tentang apa itu semaphore dan cara kerjanya. Dan untuk kali ini saya akan memberikan contoh implementasi (kode) semaphore menggunakan PHP.

Mari kita mulai. Contoh: terdapat dua pekerja yang memakai resource yang sama. Dimana pekerja 1 lebih lambat bekerja, setiap pekerjaan dapat diselesaikan dalam waktu 5 detik. Kemudian pekerja 2 sangat cepat sekali dalam menyelesaikan pekerjaannya, dapat menyelesaikan setiap pekerjaan dalam waktu 1 detik. Namun pekerjaan ini tidak boleh dikerjakan dalam waktu bersama-sama, karena memakai resource yang sama, dimana pekerja 2 tidak dapat melanjutkan pekerjaan selanjutnya jika pekerja 1 belum selesai dalam menyelesaikan pekerjaannya. Anggap saja resource yang saya maksud adalah sebuah sekop.

Secara garis besar, aturan yang dipakai adalah:

  1. Sekop hanya boleh dipakai 1 pekerja dalam 1 waktu pekerjaan
  2. Pekerja 1 mempunyai waktu 5 detik untuk menyelesaikan setiap pekerjaannya
  3. Pekerja 2 mempunyai waktu 1 detik untuk menyelesaikan setiap pekerjaannya
  4. Pekerja 2 boleh mengerjakan pekerjaan selanjutnya setelah pekerja 1 selesai
  5. Pekerja 1 boleh mengerjakan pekerjaan selanjutnya setelah pekerja 2 selesai
  6. Pekerja 1 akan berjalan terlebih dahulu, kemudian dilanjutkan pekerja 2 dalam rentang waktu yang tidak lama setelah pekerja 1 berjalan

Source Code PHP Semaphore

Berikut adalah kode untuk Pekerja 1 (pekerja1.php):

<?php
// #!/usr/bin/php -q

$key = 123; // key untuk pekerja 1 dan pekerja 2 sama
$max = 1; // max proses yang bisa mendapatkan semaphore secara bersamaan
$permissions = 0666; // default adalah 0666
$auto_release = 1; // set apakah semaphore otomatis dilepaskan

// membuat atau mendapatkan semaphore
$semaphore = sem_get($key, $max, $permissions, $auto_release);
if (!$semaphore) {
    echo "Gagal membuat/mendapatkan semaphore!\n\n";
    exit;
}

$i = 1;
while ($i <= 5) {
    echo "Mencoba memperoleh token semaphore.\n";
    sem_acquire($semaphore); // blok
    echo "Mendapatkan token semaphore.\n";
    
    $date = date("H:i:s");
    $handler = fopen("resource.txt", "a+");
    echo "Pekerjaan ke-$i.\n";
    fwrite($handler, "$date => Pekerjaan ke-$i oleh pekerja 1\n");
    fclose($handler);
    sleep(5);
    
    sem_release($semaphore); // bebaskan
    echo "Token semaphore dibebaskan.\n";
    
    $i++;
}
?>

Berikut adalah kode untuk Pekerja 2 (pekerja2.php):

<?php
// #!/usr/bin/php -q

$key = 123; // key untuk pekerja 1 dan pekerja 2 sama
$max = 1; // max proses yang bisa mendapatkan semaphore secara bersamaan
$permissions = 0666; // default adalah 0666
$auto_release = 1; // set apakah semaphore otomatis dilepaskan

// membuat atau mendapatkan semaphore
$semaphore = sem_get($key, $max, $permissions, $auto_release);
if (!$semaphore) {
    echo "Gagal membuat/mendapatkan semaphore!\n\n";
    exit;
}

$i = 1;
while ($i <= 9) {
    echo "Mencoba memperoleh token semaphore.\n";
    sem_acquire($semaphore); // blok
    echo "Mendapatkan token semaphore.\n";
    
    $date = date("H:i:s");
    $handler = fopen("resource.txt", "a+");
    echo "Pekerjaan ke-$i.\n";
    fwrite($handler, "$date => Pekerjaan ke-$i oleh pekerja 2\n");
    fclose($handler);
    sleep(1);
    
    sem_release($semaphore); // bebaskan
    echo "Token semaphore dibebaskan.\n";
    
    $i++;
}
?>

Hasil Output PHP Semaphore

Dengan Semaphore:

17:21:57 => Pekerjaan ke-1 oleh pekerja 1
17:21:58 => Pekerjaan ke-1 oleh pekerja 2
17:21:59 => Pekerjaan ke-2 oleh pekerja 2
17:22:00 => Pekerjaan ke-3 oleh pekerja 2
17:22:01 => Pekerjaan ke-4 oleh pekerja 2
17:22:02 => Pekerjaan ke-5 oleh pekerja 2
17:22:02 => Pekerjaan ke-2 oleh pekerja 1
17:22:03 => Pekerjaan ke-6 oleh pekerja 2
17:22:04 => Pekerjaan ke-7 oleh pekerja 2
17:22:05 => Pekerjaan ke-8 oleh pekerja 2
17:22:06 => Pekerjaan ke-9 oleh pekerja 2
17:22:07 => Pekerjaan ke-3 oleh pekerja 1
17:22:12 => Pekerjaan ke-4 oleh pekerja 1
17:22:17 => Pekerjaan ke-5 oleh pekerja 1

Tanpa Semaphore:

17:23:54 => Pekerjaan ke-1 oleh pekerja 1
17:23:59 => Pekerjaan ke-1 oleh pekerja 2
17:24:00 => Pekerjaan ke-2 oleh pekerja 1
17:24:05 => Pekerjaan ke-2 oleh pekerja 2
17:24:06 => Pekerjaan ke-3 oleh pekerja 1
17:24:11 => Pekerjaan ke-3 oleh pekerja 2
17:24:12 => Pekerjaan ke-4 oleh pekerja 1
17:24:17 => Pekerjaan ke-4 oleh pekerja 2
17:24:18 => Pekerjaan ke-5 oleh pekerja 1
17:24:23 => Pekerjaan ke-5 oleh pekerja 2
17:24:24 => Pekerjaan ke-6 oleh pekerja 2
17:24:25 => Pekerjaan ke-7 oleh pekerja 2
17:24:26 => Pekerjaan ke-8 oleh pekerja 2
17:24:27 => Pekerjaan ke-9 oleh pekerja 2

Dari hasil di atas terlihat dengan jelas perbedaan ketika menggunakan semaphore dan tanpa semaphore. Seperti yang kita lihat dalam percobaan tanpa semaphore, pekerja 2 mengambil jatah waktu pekerja 1, dan ini menyalahi aturan 1 dan 4, bahkan pada hasil di atas terjadi kondisi dimana pekerja 1 dan pekerja 2 mengerjakan pekerjaan dalam waktu yang bersamaan (pada jam 17:22:02). Berbanding terbalik dengan hasil menggunakan semaphore, semua aturan ditaati. Pekerja 2 mengerjakan pekerjaannya setelah pekerja 1 selesai, begitu juga dengan pekerja 1, pekerja 1 mengerjakan pekerjaannya setelah pekerja 2 selesai.

Demikian sudah saya jelaskan cara kerja semaphore dan pengaplikasiannya menggunakan PHP. Semoga tulisan ini bermanfaat :)

Multiproses (Forking) di PHP (Bagian 1)PHP Semaphore (Bagian 1)