Process ID numerik menamai sebuah proses hanya selama PID tersebut masih dialokasikan kepadanya. Setelah proses keluar dan di-reap, Linux dapat menggunakan kembali angka itu untuk proses lain. Kode yang mengamati PID, melakukan pekerjaan lain, lalu bertindak memakai angka tersebut dapat melewati batas lifetime yang tidak dikodekan oleh integer itu sendiri. Linux pidfd menyediakan referensi berbentuk file descriptor ke sebuah proses sehingga operasi berikutnya dapat menargetkan objek proses yang direferensikan tanpa mengulang lookup PID numerik.
Interface ini spesifik untuk Linux. pidfd_open(), pidfd_send_signal(), polling pidfd, waitid() dengan P_PIDFD, dan operasi terkait merupakan API kernel, bukan properti bahasa C atau semantik proses POSIX.
pidfd_open mengubah lookup PID menjadi referensi yang dipertahankan
pidfd_open(pid, flags) meminta kernel me-resolve PID numerik dan mengembalikan file descriptor yang merujuk ke proses tersebut. Dengan flags bernilai nol, pemanggilan dapat merujuk ke thread-group leader. Kernel saat ini juga mendefinisikan PIDFD_THREAD, yang memungkinkan pidfd untuk thread individual jika didukung.
Batas penting berada pada saat resolusi. Pemanggilan yang berhasil menetapkan referensi descriptor pada titik tersebut. Operasi berikutnya yang memakai pidfd tidak me-resolve PID numerik awal lagi, sehingga penggunaan ulang PID di kemudian waktu tidak dapat mengalihkan descriptor itu ke proses lain.
Hal ini tidak membuat state proses immutable. Proses yang direferensikan dapat keluar setelah pidfd_open() berhasil. pidfd mempertahankan identitas, bukan liveness. Operasi setelah proses keluar melaporkan perilaku yang ditetapkan API masing-masing dan tidak diam-diam beralih ke proses baru yang memperoleh angka PID sama.
PIDFD_NONBLOCK juga dapat diberikan pada kernel yang mendukungnya. Flag tersebut memengaruhi operasi seperti waiting melalui descriptor; flag itu tidak dengan sendirinya mengubah lifetime proses menjadi event stream.
Signaling melalui pidfd menutup celah penggunaan ulang PID
Signaling tradisional dengan kill(pid, sig) me-resolve PID numerik ketika kill() dieksekusi. Jika kode memperoleh PID lebih awal dan proses awal hilang pada interval tersebut, penggunaan ulang menciptakan race antara observasi dan tindakan.
pidfd_send_signal(pidfd, sig, info, flags) mengarahkan operasi melalui referensi proses yang dipertahankan. Pemeriksaan permission tetap berlaku. pidfd bukan token otoritas yang melewati kontrol akses signal Linux; perubahan utamanya berada pada resolusi identitas target.
Perbedaan ini berguna pada supervisor dan process manager yang menyimpan handle selama pekerjaan asinkron. Descriptor dapat disimpan bersama referensi resource lain dan diberikan kepada komponen yang akhirnya melakukan operasi signal. Komponen penerima tidak perlu mengandalkan integer lama untuk tetap menunjuk lifetime yang sama.
Memberikan signal nomor nol mempertahankan bentuk pemeriksaan signal konvensional: tidak ada signal yang dikirim, sementara kernel tetap melakukan pemeriksaan target dan permission sesuai definisi interface. Hasilnya tetap operasi point-in-time dan tidak menjamin proses terus hidup sesudahnya.
Poll readiness mengekspos process exit melalui mekanisme descriptor
pidfd dapat digunakan bersama poll(), select(), dan epoll. Untuk pidfd proses, readiness berkaitan dengan terminasi proses yang direferensikan, sehingga observasi lifecycle proses dapat berada dalam event loop yang sama dengan socket, timer, dan descriptor lain.
Readiness merupakan state level-oriented, bukan record byte yang dikonsumsi. Tidak ada kewajiban melakukan read() pada pidfd untuk membersihkan event exit. Descriptor mengidentifikasi proses dan mengekspos poll state; exit status diperoleh melalui interface waiting ketika caller memiliki relasi yang diperlukan untuk me-reap atau menginspeksinya.
Pemisahan ini penting pada desain event loop. epoll_wait() dapat mengidentifikasi child yang telah berakhir, sedangkan waitid(P_PIDFD, ...) dapat mengambil wait state terkait tanpa mengubah event kembali menjadi lookup PID numerik.
pidfd yang menjadi readable juga tidak berarti setiap caller dapat me-reap proses tersebut. Aturan waiting tetap bergantung pada relasi parent-child dan semantik wait. Descriptor readiness dan otoritas untuk mengonsumsi child status merupakan kontrak yang terpisah.
P_PIDFD mengikat seleksi wait ke identitas yang sama
Linux memperluas waitid() dengan P_PIDFD. Argumen id berisi nilai pidfd, sehingga pemilihan child didasarkan pada referensi descriptor, bukan angka PID.
Bagi supervisor yang membuat child dan mempertahankan pidfd-nya, mekanisme ini menyatukan dua tahap yang jika tidak memakai model penamaan berbeda: readiness dapat tiba pada descriptor, dan pengambilan status dapat memilih descriptor yang sama. Penggunaan ulang PID di antara kedua tahap tidak dapat mengalihkan wait ke target lain.
WNOWAIT tetap relevan ketika status perlu diamati tanpa langsung mengonsumsi waitable state. Flag ini membiarkan child tetap berada dalam kondisi waitable untuk wait berikutnya. pidfd menstabilkan identitas target, sedangkan wait flags mengontrol semantik konsumsi status.
pidfd nonblocking dapat membuat waitid() mengembalikan EAGAIN ketika child terpilih belum berakhir dan operasi seharusnya memblokir. Perilaku ini berasal dari kombinasi API pidfd dan wait, bukan dari semantik nonblocking file descriptor generik untuk semua operasi proses.
pidfd_getfd menduplikasi descriptor target dengan aturan akses terpisah
pidfd_getfd(pidfd, targetfd, flags) dapat menduplikasi file descriptor dari proses yang direferensikan ke caller. Descriptor hasil merujuk ke open file description yang sama dengan descriptor target, sehingga file offset dan status flags yang terkait dengan open file description tersebut ikut dibagi.
pidfd kembali menyediakan identitas proses yang stabil, tetapi tidak memberikan hak tanpa batas untuk mengambil descriptor. Linux menerapkan pemeriksaan akses bergaya ptrace pada operasi ini. Policy namespace, credential, capability, dan security module karena itu dapat mencegah akses walaupun caller memiliki pidfd.
Ada pula batas concurrency pada targetfd. Integer tersebut diinterpretasikan di dalam proses yang direferensikan ketika pidfd_getfd() dieksekusi. Jika proses itu menutup dan menggunakan kembali nomor descriptor sebelum pemanggilan, operasi dapat memilih descriptor yang lebih baru. pidfd menghapus ambiguitas identitas proses; pidfd tidak membekukan descriptor table milik target.
Perbedaan tersebut penting dalam desain API berbasis handle. Identitas stabil pada satu lapisan tidak otomatis menstabilkan nama turunan di dalam objek yang direferensikan.
Transfer descriptor mempertahankan referensi proses
Karena pidfd adalah file descriptor, descriptor ini dapat diwariskan melalui fork() sesuai descriptor flags dan dapat ditransfer melalui Unix domain socket memakai SCM_RIGHTS. Proses penerima memperoleh descriptor yang merujuk ke identitas proses yang sama.
Mekanisme ini memungkinkan komponen yang melakukan pembuatan atau discovery proses menyerahkan referensi stabil kepada komponen lain. Sisi penerima tidak perlu mengulang resolusi PID. Pemeriksaan akses normal untuk operasi pidfd berikutnya tetap berlaku ketika operasi tersebut mendefinisikannya.
Policy close-on-exec juga relevan. pidfd yang dikembalikan pidfd_open() memiliki close-on-exec aktif, sehingga propagasi tidak disengaja melalui execve() dapat dicegah kecuali aplikasi sengaja mengubah descriptor flags. Transfer eksplisit dengan demikian berbeda dari inheritance akibat penggantian program.
Lifetime descriptor tidak bergantung pada kemampuan target untuk terus berjalan. Memegang pidfd tidak menjaga proses tetap hidup. Descriptor mempertahankan referensi kernel yang sesuai untuk operasi sensitif terhadap identitas dan observasi sampai descriptor itu sendiri ditutup.
Referensi proses mempersempit race tanpa menciptakan transaksi
pidfd mengganti langkah penamaan yang rapuh dengan referensi kernel yang dipertahankan. Mekanisme ini menutup kelas race tertentu ketika PID numerik di-resolve lebih dari sekali melintasi batas asinkron. pidfd tidak melakukan serialisasi terhadap proses target, tidak membekukan resource-nya, tidak mempertahankan address space, dan tidak membuat beberapa operasi pidfd menjadi atomic sebagai satu grup.
Proses dapat keluar di antara dua operasi pada pidfd yang sama. Descriptor table miliknya dapat berubah ketika proses lain memegang pidfd. State permission juga dapat membuat operasi gagal walaupun descriptor tetap valid. Desain yang tepat karena itu memperlakukan pidfd sebagai handle identitas stabil dengan semantik spesifik per operasi, bukan snapshot state proses.
Kontrak yang lebih sempit tersebut sekaligus menjadi nilai arsitekturalnya. Signaling, readiness, waiting, dan operasi lintas proses tertentu dapat berbagi satu representasi identitas proses, sementara setiap API tetap mempertahankan aturan lifetime, permission, dan transisi state masing-masing.