Pada tulisan Multiproses (Forking) di PHP (Bagian 1), saya sudah menjelaskan sedikit tentang apa itu multiproses dan kegunaannya. Dan untuk kali ini saya akan memberikan contoh implementasi (kode) multiproses (forking) di bahasa pemrograman PHP.
Fungsi-fungsi PHP untuk menangani multiproses masuk dalam kategori Process Control Functions. Semua fungsi-fungsi tersebut berawalan pcntl_*
. Kontrol proses dalam PHP mengikuti kaidah Unix dalam penciptaan proses, eksekusi program, penanganan sinyal, dan terminasi proses.
Mari Mulai
Pertama, semua proses memiliki ID yang unik yang disebut PID. PID merupakan referensi untuk suatu proses yang dapat digunakan untuk mengirimkan sinyal dan lainnya. Semua proses juga memiliki PPID yang merupakan referensi untuk proses induk (proses yang menciptakan proses), namun biasanya bernilai 0 (nol) yang berarti tidak ada parent process. Baiklah, saya contohkan suatu kode sederhana dalam menciptakan suatu proses. PHP Fork (phpfork.php
):
<?php
// #!/usr/bin/php -q
$pid = pcntl_fork(); // Fungsi untuk menciptakan proses
if ($pid) {
echo "Aku adalah proses orang tua!\n";
} else {
echo "Aku adalah proses anak!\n";
}
?>
Ketika fungsi pcntl_fork()
dideklarasikan, eksekusi kode akan berjalan seperti biasa dan pada saat itu pula pcntl_fork()
akan membuat salinan terhadap dirinya sendiri. Fungsi pcntl_fork()
pada dasarnya adalah menyalin suatu proses. Ketika pcntl_fork()
dijalankan, PID proses anak akan dikembalikan ke orang tua saat terjadi eksekusi kode. Namun untuk anak, nilai PID akan bernilai 0 (nol) saat eksekusi kode. Karena terdapat perbedaan eksekusi pada blok orang tua dan anak, maka kita dapat membuat sesuatu yang berbeda pula antara proses orang tua dan anak tersebut. Di bawah ini adalah hasil dari kode di atas saat dieksekusi.
Output yang dikeluarkan:
Aku adalah proses orang tua!
Aku adalah proses anak!
atau dapat berupa seperti ini:
Aku adalah proses anak!
Aku adalah proses orang tua!
Karena fungsi pcntl_fork()
pada dasarnya adalah menyalin suatu proses, jadi apa yang terjadi jika kita merubah sedikit kode di atas seperti di bawah ini? PHP Fork (phpfork.php
):
<?php
// #!/usr/bin/php -q
$pid = pcntl_fork();
if ($pid) {
echo "Aku adalah proses orang tua!\n";
} else {
echo "Aku adalah proses anak!\n";
}
echo "Eksekusi selesai.\n";
?>
Di bawah ini adalah hasil dari kode di atas saat dieksekusi:
Aku adalah proses orang tua!
Eksekusi selesai.
Aku adalah proses anak!
Eksekusi selesai.
atau dapat pula berupa seperti ini:
Aku adalah proses anak!
Eksekusi selesai.
Aku adalah proses orang tua!
Eksekusi selesai.
Hasilnya, deklarasi kode yang terdapat di luar blok kondisi (if statement) akan tereksekusi pula di kedua proses tersebut.
Menunggu Proses Anak
Satu permasalahan yang terjadi saat menerapkan multiproses dan multithread adalah kita tidak tahu proses mana yang akan dieksekusi terlebih dahulu, apakah itu proses anak atau proses orang tua. Kadang kala kita pasti membutuhkan agar proses anak dieksekusi terlebih dahulu sebelum proses orang tua ataupun sebaliknya. Beruntung PHP menyediakan fungsi untuk mengatasi hal tersebut. Dengan menggunakan fungsi pcntl_wait()
, proses orang tua akan selalu menunggu supaya proses anak selesai terlebih dahulu.
<?php
// #!/usr/bin/php -q
$pid = pcntl_fork();
if ($pid) {
pcntl_wait($status);
echo "Aku adalah proses orang tua!\n";
} else {
echo "Aku adalah proses anak!\n";
}
?>
Hasil eksekusi kode di atas akan selalu menghasilkan output seperti di bawah ini.
Aku adalah proses anak!
Aku adalah proses orang tua!
Demikian contoh sederhana implementasi multiproses pada bahasa pemrograman PHP. Pada tulisan selanjutnya, saya akan jelaskan mengenai signals yang digunakan untuk komunikasi dan sinkronisasi proses.