Pada nya halaman web tentang para trik self-pipa , Dan Bernstein menjelaskan kondisi ras dengan select()
dan sinyal, menawarkan solusi dan menyimpulkan bahwa
Tentu saja, Hal yang Benar adalah
fork()
mengembalikan deskriptor file, bukan ID proses.
Apa yang dia maksudkan dengan ini - apakah ini sesuatu tentang kemampuan select()
proses anak untuk menangani perubahan status mereka alih-alih harus menggunakan penangan sinyal untuk mendapat pemberitahuan tentang perubahan status itu?
signals
file-descriptors
fork
Lassi
sumber
sumber
signalfd
dan itu adalah hal yang dulu?wait()
, ada hal-hal yang tidak dapat Anda lakukan, jadi seseorang menemukan SIGCHLD, tetapi itu adalah pekerjaan yang buruk. Dalam pengalaman saya, dan sekarang bahwa mereka ada, percikan bagus, nonblockingwait3()
,wait4()
dan / atauwaitpid()
panggilan di tempat-tempat kunci (mungkin Anda acara loop utama) adalah alternatif yang jauh lebih unggul.Jawaban:
Masalahnya dijelaskan di sana di sumber Anda,
select()
harus terganggu oleh sinyal sepertiSIGCHLD
, tetapi dalam beberapa kasus itu tidak berfungsi dengan baik. Jadi solusinya adalah memiliki sinyal menulis ke pipa, yang kemudian ditontonselect()
. Menonton deskriptor file adalah untuk apaselect()
, sehingga bisa mengatasi masalah.Solusinya pada dasarnya mengubah acara sinyal menjadi acara deskriptor file. Jika
fork()
hanya mengembalikan fd di tempat pertama, solusi tidak akan diperlukan, karena fd itu kemudian dapat digunakan secara langsungselect()
.Jadi ya, uraian Anda pada paragraf terakhir sepertinya tepat bagi saya.
Alasan lain bahwa fd (atau jenis lain dari pegangan kernel) akan lebih baik daripada nomor proses id, adalah bahwa PID dapat digunakan kembali setelah proses mati. Itu bisa menjadi masalah dalam beberapa kasus ketika mengirim sinyal ke proses, mungkin tidak mungkin untuk mengetahui dengan pasti bahwa prosesnya adalah yang Anda pikirkan, dan bukan yang lain menggunakan kembali PID yang sama. (Meskipun saya pikir ini seharusnya tidak menjadi masalah ketika mengirim sinyal ke proses anak, karena orang tua harus menjalankan
wait()
pada anak untuk PID yang akan dirilis.)sumber
wait()
.clone
, yang merupakan panggilan sistem aktual yang dipanggil oleh garpu pada LInux. Bendera untuk mengaktifkan ini disebutCLONE_PIDFD
- Lihat misalnya lwn.net/Articles/784831 .Itu hanya merenung di baris "akan lebih bagus jika Unix dirancang berbeda dari itu".
Masalah dengan PID adalah bahwa mereka hidup di ruang nama global tempat mereka dapat digunakan kembali untuk proses lain, dan alangkah baiknya jika
fork()
dikembalikan pada orang tua semacam pegangan yang akan dijamin untuk selalu merujuk pada proses anak, dan bahwa itu bisa lewat ke proses lain melalui warisan atau soket unix /SCM_RIGHTS
[1].Lihat juga diskusi di sini untuk upaya baru-baru ini untuk "memperbaikinya" di Linux, termasuk menambahkan bendera
clone()
yang akan menyebabkannya mengembalikan pid-fd bukan PID.Tetapi meskipun begitu, itu tidak akan menghilangkan kebutuhan untuk hack pipa-diri [2] atau antarmuka yang lebih baik, karena sinyal yang memberitahukan proses induk tentang keadaan anak bukan satu-satunya yang ingin Anda tangani dalam loop utama dari program ini. Sayangnya, hal-hal seperti
epoll(7) + signalfd(2)
di Linux ataukqueue(2)
BSD tidak standar - satu-satunya antarmuka standar (tetapi tidak didukung pada sistem yang lebih tua) adalah yang jauh lebih rendahpselect(2)
.[1] Mencegah PID agar tidak didaur ulang pada saat
waitpid()
syscall telah kembali dan nilai kembalinya digunakan mungkin dapat dicapai pada sistem yang lebih baru dengan menggunakanwaitid(.., WNOWAIT)
sebagai gantinya.[2] Saya tidak akan mengomentari klaim DJ Bernstein bahwa ia menciptakannya (maaf atas apofasis ;-)).
sumber
Bernstein tidak memberikan banyak konteks untuk pernyataan "Right Thing" ini, tetapi saya akan menebak: memiliki fork (2) mengembalikan PID tidak konsisten dengan open (2), creat (2) dll yang kembali deskriptor file. Sisanya dari sistem Unix bisa melakukan manipulasi proses dengan deskriptor file yang mewakili suatu proses, bukan PID. System call signalfd (2) ada, yang memungkinkan interaksi yang agak lebih baik antara sinyal dan deskriptor file, dan menunjukkan bahwa file-deskriptor yang mewakili suatu proses dapat bekerja.
sumber
pidfd_open
di Linux, lihat misalnya lwn.net/Articles/789023