Konteks dan cakupan
PID numerik dapat digunakan kembali setelah suatu proses berhenti, sehingga sinyal atau pemeriksaan status yang tertunda dapat menargetkan proses yang salah. Linux menyediakan pidfd_open() untuk deskriptor file yang merujuk ke suatu proses dan pidfd_send_signal() untuk mengirimkan sinyal ke proses tersebut. Keterampilan intinya adalah pemrograman sistem dan kebenaran siklus hidup, jadi ini adalah pertanyaan coding.
Apa yang dinilai oleh pewawancara
Jawaban yang kuat menjelaskan identitas deskriptor, kesiapan poll atau epoll, integrasi waitid, close-on-exec, izin (permissions), dan pembersihan (cleanup). Jawaban tersebut membedakan pidfd dari handle proses yang memberikan akses tak terbatas, menangani race condition pada fork/exec, dan menentukan perilaku untuk exit, restart, timeout, dan crash pada supervisor. Mereka juga menyebutkan deteksi fitur versi kernel dan fallback yang telah diuji.
Pertanyaan klarifikasi awal
- Versi kernel dan namespace mana yang harus didukung oleh supervisor?
- Apakah supervisor meluncurkan proses anak sendiri, atau menempel pada proses yang sudah ada?
- Apakah supervisor harus mengamati status exit, mengirim sinyal, atau keduanya?
- Bisakah worker melakukan fork untuk proses turunan, dan siapa yang bertanggung jawab atas pembersihannya?
- Apa jaminan untuk timeout, restart, dan crash pada supervisor?
- Apakah fallback diperlukan pada kernel tanpa dukungan pidfd?
Kerangka jawaban 30 detik
“Saya akan mendapatkan pidfd untuk setiap proses yang dikelola dan menyimpan deskriptornya, bukan hanya PID numeriknya. Tambahkan deskriptor ke poll atau epoll, gunakan operasi wait yang terdokumentasi untuk mengumpulkan status, dan panggil pidfd_send_signal() untuk timeout atau shutdown. Tetapkan close-on-exec, tutup deskriptor pada setiap jalur terminal, dan perlakukan kesiapan beserta pengumpulan status sebagai satu state machine siklus hidup. Saya akan menguji penggunaan ulang PID, exit yang cepat, kesalahan izin, anak proses hasil fork, deteksi fitur kernel, dan restart supervisor.”
Jawaban langkah demi langkah
Langkah 1: Dapatkan dan miliki deskriptor
Setelah meluncurkan atau menemukan suatu proses, panggil pidfd_open() jika didukung dan catat deskriptornya dalam tabel kepemilikan. Tandai sebagai close-on-exec dan simpan PID numerik hanya untuk pencatatan log. Jangan meneruskan deskriptor ke worker yang tidak terkait tanpa transfer kepemilikan yang eksplisit.
Langkah 2: Amati event siklus hidup
Daftarkan pidfd ke poll atau epoll. Kesiapan menandakan proses yang dirujuk telah berhenti; kumpulkan statusnya dengan operasi wait yang sesuai lalu tutup deskriptornya. Jangan menyimpulkan keaktifan dari path /proc yang usang atau nilai integer PID.
Langkah 3: Kirim sinyal ke proses yang tepat
Gunakan pidfd_send_signal() untuk penghentian bertahap (graceful termination) dan eskalasi. Tangani kesalahan izin dan namespace secara eksplisit. Suatu pidfd mengidentifikasi proses yang dirujuk bahkan jika PID numeriknya kemudian digunakan kembali, tetapi pidfd tidak menggantikan pemeriksaan otorisasi.
Langkah 4: Modelkan restart dan proses turunan
Representasikan setiap worker sebagai starting, running, stopping, exited, atau failed. Saat restart, buat pidfd dan catatan generasi yang baru. Tentukan apakah proses turunan berada dalam grup proses yang sama, cgroup, atau domain kepemilikan terpisah; jangan pernah berasumsi bahwa mengirim sinyal ke induk akan membersihkan setiap anak proses.
Langkah 5: Uji batas race condition dan portabilitas
Lakukan uji stres terhadap exit yang cepat dan penggunaan ulang PID, sinyal yang bersamaan dengan exit, kehabisan deskriptor, crash pada supervisor, perubahan namespace, dan kernel yang tidak didukung. Bandingkan dengan fallback yang dibatasi secara hati-hati seperti waitpid untuk anak langsung, dan catat jaminan apa saja yang tidak dapat diberikan oleh fallback tersebut.
Contoh jawaban model
“Cacat ini muncul dari penggunaan integer yang dapat digunakan kembali sebagai identitas proses. Saya akan menyimpan pidfd untuk setiap worker, mendaftarkannya ke event loop, mengumpulkan status exit setelah terjadi kesiapan, dan mengirim sinyal melalui pidfd_send_signal() untuk penghentian bertahap dan eskalasi. Kepemilikan deskriptor, close-on-exec, izin, dan pembersihan proses turunan menjadi aturan state-machine yang eksplisit. Setiap restart mendapatkan generasi dan pidfd baru. Pengujian harus memaksakan exit yang cepat dan penggunaan ulang PID, mencakup dukungan namespace dan kernel, serta mendokumentasikan jaminan yang lebih lemah dari fallback anak langsung.”
Kesalahan umum
- Hanya menyimpan PID numerik → sinyal yang tertunda berpacu dengan penggunaan ulang PID → pertahankan pidfd.
- Melakukan polling pada
/procuntuk memeriksa keaktifan → pengamatan menjadi usang → gunakan kesiapan pidfd dan pengumpulan status. - Mengasumsikan pidfd mengabaikan izin → pengiriman sinyal tetap memerlukan otorisasi → tangani kesalahan izin.
- Membocorkan deskriptor saat exec → program yang tidak terkait mewarisi handle siklus hidup → tetapkan close-on-exec.
- Hanya mematikan proses induk → proses turunan menjadi yatim piatu (orphaned) → tentukan kepemilikan grup atau cgroup.
- Memperlakukan kesiapan sebagai status lengkap → penanganan kode exit menjadi tidak lengkap → kumpulkan dan simpan status wait.
Pertanyaan lanjutan
Pertanyaan lanjutan 1: Apakah pidfd mencegah penggunaan ulang PID?
Pidfd menyediakan referensi deskriptor yang stabil ke proses untuk operasi yang menerima pidfd. PID numerik mungkin digunakan kembali, tetapi operasi melalui deskriptor tersebut tetap merujuk ke proses aslinya.
Pertanyaan lanjutan 2: Bisakah Anda menggunakan pidfd dengan epoll?
Ya, pidfd dapat di-poll untuk mendeteksi penghentian proses, sehingga dapat berpartisipasi dalam event loop supervisor bersama pipes, timer, dan socket kontrol.
Pertanyaan lanjutan 3: Bagaimana jika kernel tidak memiliki dukungan pidfd?
Deteksi kapabilitas saat startup dan gunakan fallback terdokumentasi untuk anak langsung, sambil mengekspos jaminan race condition dan observabilitas yang lebih lemah daripada berpura-pura setara.
Pertanyaan lanjutan 4: Apa yang terjadi setelah supervisor melakukan restart?
Pertahankan metadata kepemilikan yang cukup untuk menemukan kembali atau sengaja mengabaikan worker, lalu buat ulang status pemantauan dan pidfd. Jangan pernah hanya memercayai PID numerik yang disimpan.