PID numerik dapat menunjuk satu proses saat ini dan proses lain pada waktu berikutnya. PID file descriptor di Linux mengubah batas tersebut: pidfd adalah file descriptor yang merujuk sebuah task, sehingga operasi proses dapat tetap terikat pada objek kernel yang dituju tanpa mengulang pencarian berdasarkan PID numerik.

Perbedaan ini relevan bagi supervisor, service manager, container runtime, dan perangkat lunak lain yang mengamati siklus hidup proses. PID berguna sebagai nama, tetapi bukan capability yang tahan terhadap penggunaan ulang. Pidfd dapat dipertahankan selama jeda antara identifikasi proses dan operasi terhadap proses tersebut.

Penggunaan ulang PID menciptakan race identitas

Pola kontrol proses yang umum menyimpan PID lalu memakainya kembali:

amati PID 4812
      ├── target exit
      ├── PID 4812 dapat dipakai ulang
      └── task lain menerima PID 4812
          operasi berikutnya via PID

Masalahnya bukan penggunaan ulang PID itu sendiri. Kernel memang dapat menggunakan kembali nomor PID. Race muncul ketika aplikasi menganggap nomor yang diamati sebelumnya masih menunjuk task yang sama pada operasi berikutnya.

Memeriksa /proc/4812, lalu menjalankan kill(4812, SIGTERM), tidak membuat kedua operasi itu menjadi satu pemeriksaan identitas atomik. Target dapat exit di antara keduanya. Proses baru kemudian dapat menerima PID tersebut.

Pidfd memindahkan referensi identitas ke file descriptor yang dikelola kernel:

PID 4812 ── pidfd_open() ──► fd 7
                              ├── poll / epoll
                              ├── pidfd_send_signal()
                              └── close()

Setelah diperoleh, fd 7 merujuk task yang terkait dengan pidfd tersebut, bukan meminta operasi berikutnya mencari PID 4812 lagi.

pidfd_open mengikat descriptor ke task yang sudah ada

pidfd_open() memperoleh PID file descriptor untuk task yang sudah ada. Descriptor yang dikembalikan memiliki close-on-exec. Linux juga mendukung pembuatan child sekaligus memperoleh pidfd melalui clone() atau clone3() dengan CLONE_PIDFD.

Kedua jalur tersebut berlaku pada titik siklus hidup yang berbeda:

task yang sudah ada:
    PID numerik → pidfd_open() → pidfd

child baru:
    clone3(CLONE_PIDFD) → child + pidfd

Untuk task yang sudah berjalan, pidfd_open() merupakan interface langsung. Untuk kode yang membuat child sendiri, memperoleh descriptor saat proses dibuat menghindari pencarian PID terpisah setelah pembuatan.

Pidfd tetap mengikuti aturan lifecycle file descriptor. Duplikasi dengan dup() membuat descriptor lain untuk open file description yang sama, sedangkan close() melepaskan sebuah referensi descriptor.

Exit proses menjadi input event loop

PID file descriptor dapat dipantau. poll(), select(), dan epoll dapat melaporkan readiness ketika task yang dirujuk berhenti dan menjadi zombie. Setelah task di-reap, polling dapat melaporkan event hangup.

Dengan sifat ini, status siklus hidup proses dapat berada dalam event loop yang sama dengan socket, timer, dan objek pollable lain:

epoll
  ├── listening socket
  ├── client socket
  ├── timerfd
  └── pidfd ──────────► child exit

Event readiness tersebut adalah sinyal lifecycle, bukan byte stream. Membaca pidfd tidak menghasilkan record exit; read() pada descriptor gagal dengan EINVAL pada implementasi Linux saat ini.

Untuk child process, waitid() dapat memakai P_PIDFD dengan pidfd yang sesuai. Pidfd menyediakan identitas stabil, sedangkan interface wait menyediakan status child dan semantik menunggu proses.

Sinyal melalui pidfd menghindari pencarian PID kedua

pidfd_send_signal() mengirim sinyal ke task yang dirujuk oleh pidfd. Properti identitas utamanya berbeda dari kill():

kill(pid, sig)
    pencarian PID numerik saat operasi

pidfd_send_signal(pidfd, sig, ...)
    operasi melalui referensi task yang dipertahankan

Pemeriksaan izin tetap berlaku. Pidfd bukan jalur untuk melewati otorisasi sinyal Linux. Perubahan ada pada identifikasi target, bukan kebijakan keamanan yang mengatur pengiriman sinyal.

Pemisahan ini penting bagi supervisor dengan privilege. Referensi stabil mencegah operasi salah sasaran akibat penggunaan ulang PID, tetapi tidak memberikan otoritas arbitrer atas task yang dirujuk.

Descriptor direktori proc bukan pengganti penuh

Membuka /proc/<pid> juga dapat mempertahankan referensi yang berkaitan dengan proses, dan beberapa operasi pidfd menerima descriptor yang diperoleh dari procfs. Namun descriptor tersebut bukan pengganti penuh pidfd dari interface khusus.

Descriptor /proc/<pid> bergantung pada procfs yang ter-mount. Descriptor itu juga tidak pollable untuk exit proses dan tidak dapat dipakai dengan waitid() sebagai PID file descriptor dengan cara yang sama seperti descriptor dari pidfd_open().

API pidfd khusus karena itu memberi lebih dari sekadar handle pathname yang tampak persisten. API tersebut mengintegrasikan identitas proses dengan model event dan kontrol berbasis file descriptor.

pidfd tidak membuat seluruh kontrol proses menjadi atomik

Identitas target yang stabil menghapus satu race penting, tetapi tidak membuat kebijakan kontrol bertahap menjadi atomik. Supervisor tetap dapat mengamati state aplikasi, mengambil keputusan, lalu mendapati state lain berubah sebelum operasi berikutnya.

Contohnya:

periksa state service
        ├── keputusan policy
        └── pidfd_send_signal()

Pidfd menjaga sinyal tetap terarah ke task yang dimaksud. Pidfd tidak membekukan task, credentials, namespaces, atau state service eksternal di antara pemeriksaan dan pengiriman sinyal.

Batas jaminannya tetap spesifik: pidfd menstabilkan identitas proses pada operasi yang mendukungnya. Sinkronisasi tingkat aplikasi dan konsistensi policy tetap menjadi tanggung jawab aplikasi.

Identitas file descriptor cocok untuk supervisi event-driven Linux

Linux mengekspos banyak mekanisme asinkron sebagai file descriptor. Pidfd memperluas model tersebut ke pengamatan siklus hidup proses dan sejumlah operasi proses.

Supervisor dapat mempertahankan pidfd, mendaftarkannya ke epoll, merespons readiness saat exit, memakai interface wait untuk child jika berlaku, dan mengarahkan operasi yang didukung melalui referensi task stabil yang sama. PID numerik tetap berguna untuk tampilan, log, dan interface yang memang memerlukannya, tetapi tidak perlu lagi menanggung seluruh fungsi identitas proses.

Batas praktisnya ringkas: PID adalah nomor yang dapat dipakai ulang dalam PID namespace; pidfd adalah referensi kernel yang dipertahankan, dapat dipantau, dan dapat digunakan oleh system call yang mendukung pidfd.