PID numerik Linux dapat dipakai ulang setelah prosesnya berakhir. Sebaliknya, PID file descriptor merujuk ke task tertentu, sehingga operasi berikutnya melalui descriptor tersebut tidak diam-diam beralih ke proses lain yang kemudian memperoleh PID numerik yang sama.
Sifat ini mengubah identitas proses dari lookup yang diulang pada setiap operasi menjadi referensi yang dipertahankan kernel dengan semantik descriptor. Perbedaannya relevan untuk pengiriman signal, pemantauan exit, dan event loop yang menyimpan handle proses selama pekerjaan asinkron berlangsung.
PID numerik adalah nama dalam namespace yang dapat dipakai ulang
Interface seperti kill(pid, sig) me-resolve PID numerik ketika operasi dijalankan. Jika perangkat lunak menyimpan PID, menjalankan pekerjaan lain, lalu memakai angka itu kembali, proses asal mungkin sudah berakhir dan angkanya telah diberikan kepada proses lain.
Pemeriksaan keberadaan proses tidak membuat operasi berbasis PID berikutnya atomik terhadap pemeriksaan tersebut. Pemeriksaan yang berhasil lalu diikuti pengiriman signal terpisah tetap menyisakan kemungkinan perubahan state di antara kedua call.
pidfd menghilangkan race identitas khusus ini. pidfd_open() memperoleh descriptor yang merujuk ke task yang dipilih saat akuisisi. Jika task tersebut kemudian berakhir, descriptor tidak mulai merujuk ke proses pengganti.
Pengiriman signal memakai referensi yang dipertahankan
pidfd_send_signal() menargetkan task yang direpresentasikan pidfd, bukan melakukan lookup PID numerik baru.
int pidfd = syscall(SYS_pidfd_open, pid, 0);
if (pidfd == -1)
return -1;
if (syscall(SYS_pidfd_send_signal, pidfd, SIGTERM, NULL, 0) == -1)
return -1;Pemeriksaan izin tetap berlaku. Referensi yang stabil tidak memberikan otoritas yang tidak dimiliki caller.
Jika proses yang dirujuk telah berakhir, pidfd_send_signal() gagal dengan ESRCH; signal tidak dialihkan ke proses baru yang kebetulan memiliki PID sama. Ini adalah properti identitas utama yang diberikan descriptor.
State exit dapat dipantau dengan poll
pidfd dapat digunakan dalam poll(), select(), dan epoll. Untuk pidfd yang merujuk ke proses, readiness dilaporkan ketika proses tersebut berakhir dan menjadi zombie. Setelah proses di-reap, polling juga dapat melaporkan kondisi hangup.
struct pollfd pfd = {
.fd = pidfd,
.events = POLLIN,
};
int rc = poll(&pfd, 1, -1);
if (rc > 0 && (pfd.revents & POLLIN)) {
/* proses yang dirujuk telah berakhir */
}Descriptor ini bukan byte stream yang membawa record exit. read() pada pidfd gagal dengan EINVAL pada implementasi yang didokumentasikan. Readiness merupakan notifikasi state proses yang melekat pada descriptor.
Bentuk ini cocok dengan event loop yang sudah memultipleks socket, timerfd, eventfd, atau signalfd. Terminasi proses dapat masuk ke readiness set yang sama tanpa probe PID numerik berkala.
Readiness dan reaping adalah operasi terpisah
pidfd yang readable menandakan terminasi; kondisi itu tidak dengan sendirinya me-reap child. Ketika pidfd merujuk ke child milik caller, waitid() dapat memakai P_PIDFD untuk memperoleh status child dan menjalankan operasi wait terkait.
Pemisahan ini mempertahankan model reaping child yang sudah ada. pidfd menyediakan identitas stabil dan pollability, sedangkan waitid() menyediakan semantik wait serta pengambilan status.
Untuk proses yang bukan child milik caller, kepemilikan pidfd tidak mengubah proses tersebut menjadi child yang dapat di-wait. Identitas descriptor tidak mengubah hubungan ancestry proses.
Lifetime descriptor terpisah dari pemakaian ulang PID
Menutup pidfd melepaskan referensi descriptor milik caller. Mempertahankannya tetap terbuka menyimpan handle ke identitas task yang sama meski namespace PID dapat memakai ulang angka tersebut.
Descriptor karena itu memiliki model lifetime yang berbeda dari penyimpanan integer di memori aplikasi. Integer tetap dapat dipakai secara sintaksis setelah referen asal hilang; pidfd tetap terikat secara semantik ke referen asal dan melaporkan operasi terhadap state tersebut.
pidfd_open() juga memasang close-on-exec pada descriptor yang dikembalikan. Retensi melewati penggantian image memerlukan perubahan eksplisit pada flag descriptor tersebut.
Thread pidfd memiliki scope identitas yang lebih sempit
Linux juga mendukung pidfd yang merujuk ke thread individual melalui interface dan flag yang meminta scope thread. Scope tersebut mengubah readiness terminasi: thread pidfd dapat menjadi readable ketika thread yang dirujuk berakhir walaupun thread lain dalam thread group masih hidup.
Karena itu, pidfd dengan scope proses dan scope thread tidak dapat diperlakukan sebagai handle yang setara. Keduanya memberi identitas stabil, tetapi objek yang lifetime-nya dilacak berbeda.
Scope signal juga dapat bergantung pada tipe pidfd dan flag signal. Kode yang menyimpan pidfd sebagai handle task generik perlu mempertahankan scope yang dimaksud sebagai bagian dari model state internalnya.
Identitas stabil tidak berarti inspeksi tanpa batas
pidfd adalah referensi, bukan capability yang melewati batas izin Linux. Operasi melalui system call terkait pidfd tetap memiliki pemeriksaan akses, batas namespace, dan persyaratan state target masing-masing.
pidfd juga tidak membekukan proses target. Credentials, namespace, memory mapping, file descriptor, dan execution state dapat berubah selama identitas proses tetap sama. Jaminannya berkaitan dengan task yang ditunjuk descriptor, bukan immutability task tersebut.
Batas teknisnya spesifik: pemakaian ulang PID numerik dapat mengubah referen dari lookup PID berikutnya, sedangkan pidfd yang sudah diperoleh tetap melekat pada task yang dipilih saat akuisisi. Linux kemudian dapat menyediakan pengiriman signal dan readiness terminasi terhadap identitas tersebut tanpa mengubah state proses menjadi data stream konvensional.