Prompt dan Bila Ia Terpakai
Satu perkhidmatan TCP Linux menetapkan kedua-dua soket pendengaran dan soket bersambung kepada mod tidak menyekat dan memacunya dengan epoll. Seorang klien telah meletakkan 8 KiB dalam penimbal terima sambungan. Selepas epoll_wait mengembalikan EPOLLIN, pengendali memanggil recv sekali, menggunakan 4 KiB, dan kembali.
Dengan mod level-triggered lalai, LT, epoll_wait seterusnya sering melaporkan sambungan itu semula. Selepas mendayakan mod edge-triggered dengan EPOLLET, ET, pelaksanaan yang sama kadangkala tidak menerima pemberitahuan boleh dibaca lagi dan klien menunggu selama-lamanya. Terangkan:
- apakah yang dimaksudkan dengan senarai minat, senarai sedia, dan kesediaan I/O
epoll; - mengapa kontrak pemberitahuan LT dan ET menghasilkan hasil yang berbeza;
- bagaimana ET harus mengendalikan
accept,recv,send,EAGAIN, penutupan separuh (half-close), dan ralat; - apakah risiko tambahan yang dibawa oleh bebenang pekerja,
EPOLLONESHOT, keadilan sambungan hangat, dan penggunaan semula FD; - bagaimana untuk mengesahkan punca dan mengesahkan pembetulan dengan eksperimen yang boleh diulang.
Nilai 8 KiB dan 4 KiB adalah input temuduga. Ia bukan saiz tetap untuk penghantaran TCP, panggilan sistem, atau mesej aplikasi. Kecekapan teras ialah kontrak kesediaan I/O Linux, yang terpakai untuk peranan backend, infrastruktur, SRE, sistem, dan kejuruteraan perisian umum, jadi kategorinya ialah general.
Perkara yang Diuji oleh Penemuduga
Pertama, bolehkah calon menyatakan bahawa epoll melaporkan kesediaan—sama ada satu kelas I/O boleh membuat kemajuan tanpa menyekat—bukan bahawa satu permintaan lengkap telah tiba dan bukan bahawa I/O tak segerak telah selesai? TCP ialah aliran bait, dan satu recv boleh mengembalikan sebarang bilangan bait positif yang tersedia pada masa itu.
Kedua, adakah mereka memahami LT dan ET melangkaui slogan? LT terus melaporkan selagi keadaan kesediaan yang diminta kekal wujud. ET tidak menjanjikan pemberitahuan lain semata-mata kerana keadaan itu kekal benar. Selepas peristiwa ET, aplikasi harus menganggap FD sebagai boleh diambil tindakan sehingga bacaan atau penulisan tidak menyekat mengembalikan EAGAIN atau EWOULDBLOCK. "ET hanya memberitahu sekali" adalah terlalu mutlak dan tidak menghasilkan pelaksanaan yang betul.
Ketiga, bolehkah mereka menggunakan peraturan yang sama untuk bacaan, penulisan, dan soket pendengaran? Habiskan bacaan hingga EAGAIN; gelung ke atas accept4 hingga EAGAIN; dan jangan pantau EPOLLOUT secara kekal pada soket yang biasanya boleh ditulis. Pantau ia hanya semasa aplikasi mempunyai data bertimbal yang belum dihantar.
Keempat, bolehkah mereka menguruskan keadaan serentak? EPOLLONESHOT menyahdayakan FD selepas satu pemberitahuan. Pekerja mesti mempersiapkannya semula dengan EPOLL_CTL_MOD selepas menyelesaikan kemas kini keadaannya. Mempersiapkan semula terlalu awal boleh membenarkan dua pekerja menyentuh satu sambungan; terlupa untuk mempersiapkan semula kelihatan seperti keadaan terhenti kekal.
Kelima, bolehkah mereka menyelaraskan "habiskan hingga EAGAIN" dengan keadilan gelung peristiwa? Sambungan yang sibuk secara berterusan mungkin menduduki bebenang terlalu lama. Jika aplikasi berhenti awal untuk menguatkuasakan keadilan, ia mesti mengekalkan sambungan tersebut dalam giliran boleh laksana ruang pengguna dan bukannya menjangkakan ET mencipta pinggir baharu.
Soalan untuk Dijelaskan Sebelum Menjawab
- Adakah soket benar-benar tidak menyekat? Dengan ET dan FD menyekat, bacaan atau penulisan seterusnya boleh menyekat bebenang yang bertanggungjawab untuk banyak sambungan.
- Adakah keadaan terhenti berlaku dalam accept, read, atau write-back? Terlepas pengosongan gelung accept, input yang tinggal, kemas kini
EPOLLOUT, atau persiapan semulaEPOLLONESHOTsemuanya boleh kelihatan seperti sambungan yang tersangkut. - Bagaimanakah protokol aplikasi mengehadkan sempadan mesej? TCP tidak mempunyai sempadan mesej. Awalan panjang, pembatas, keadaan penghurai HTTP, atau penutupan sambungan menentukan bila permintaan selesai.
- Berapa banyak yang dibaca oleh pengendali, dan bilakah ia kembali? Satu bacaan tetap bagi setiap peristiwa adalah pepijat langsung di sini; kerja perniagaan yang mahal di dalam gelung pengosongan mencipta masalah keadilan.
- Bolehkah sambungan berpindah merentasi bebenang? Kenal pasti pemilik input, output, tutup, dan
epoll_ctl, serta sama adaEPOLLONESHOTdidayakan. - Adakah
EPOLLOUTsentiasa dilanggan? Soket boleh ditulis pada kebanyakan masa. Langganan LT yang kekal boleh membuatepoll_waitkembali serta-merta dalam gelung yang membakar CPU. - Bagaimanakah
EPOLLRDHUP,EPOLLHUP, danEPOLLERRdikendalikan? Data mungkin kekal apabila HUP tiba, dan ERR/HUP dilaporkan walaupun tanpa langganan eksplisit. - Bolehkah nombor FD yang ditutup digunakan semula dengan cepat? Memperlakukan integer FD sebagai keseluruhan identiti sambungan boleh membuatkan peristiwa atau tugas yang tertangguh beroperasi pada sambungan baharu.
Jawapan 30 Saat
"epoll mengekalkan senarai minat dan mengembalikan peristiwa daripada senarai sedia. Ia melaporkan kesediaan I/O, bukan mesej lengkap. LT terus melaporkan selagi keadaan kekal sedia, jadi selepas membaca hanya 4 KiB, input yang tinggal biasanya menyebabkan penantian seterusnya mengembalikan FD tersebut semula. ET tidak menjanjikan laporan berulang untuk keadaan sedia yang tidak berubah, jadi bacaan separa boleh menunggu selama-lamanya untuk pemberitahuan yang tidak pernah tiba.
Semua FD ET mestilah tidak menyekat. Habiskan soket pendengaran dengan accept4 hingga EAGAIN, bacaan dengan recv hingga EAGAIN, dan penulisan dengan send hingga EAGAIN; pantau EPOLLOUT hanya semasa penimbal output tidak kosong. Nilai sifar recv bermaksud penutupan separuh tulis rakan setara yang teratur, manakala ralat lain memerlukan pengendalian berasingan. Dengan berbilang pekerja, EPOLLONESHOT boleh mensirikan sambungan, tetapi ia mesti dipersiapkan semula dengan MOD selepas kemas kini keadaan. Belanjawan keadilan adalah baik, tetapi berhenti sebelum EAGAIN memerlukan giliran sedia ruang pengguna. Saya akan menghasilkan semula dengan input bersegmen, bacaan dan penulisan separa, penutupan separuh, dan keserentakan, kemudian membuktikan setiap sambungan mencapai EAGAIN, dipersiapkan semula dengan betul, dan tidak melakukan gelung sibuk."
Analisis Mendalam Langkah demi Langkah
Langkah 1: Tetapkan model kesediaan epoll
epoll_create1 mencipta tika epoll, yang dirujuk oleh FD itu sendiri. Secara konsep, tika tersebut memegang dua set keadaan:
- senarai minat: FD dan topeng peristiwa yang didaftarkan melalui
epoll_ctl(EPOLL_CTL_ADD/MOD/DEL); - senarai sedia: entri senarai minat yang pada masa ini mempunyai peristiwa tersedia, yang mana
epoll_waitmengembalikan keputusan.
Boleh dibaca bermaksud bacaan pada masa ini boleh memperoleh data, EOF, atau ralat tanpa menunggu. Boleh ditulis bermaksud penulisan pada masa ini boleh membuat sekurang-kurangnya sedikit kemajuan; ia tidak menjanjikan keseluruhan respons muat. Aplikasi masih memanggil recv, send, atau accept4 dan mentafsir nilai pulangan. Peristiwa mendorong tindakan; hasil panggilan sistem memacu mesin keadaan.
Langkah 2: Bandingkan LT dan ET dengan 4 KiB yang belum dibaca
LT lalai menyerupai poll: semasa penimbal terima masih memegang data, kesediaan baca kekal benar dan epoll_wait seterusnya mungkin mengembalikan FD itu semula. Pelaksanaan yang salah iaitu "satu bacaan bagi setiap peristiwa" boleh kelihatan berfungsi, dengan kos lebih banyak bangun dan panggilan sistem.
Dengan EPOLLET, kernel melaporkan pinggir dalam kesediaan. Selepas pengendali menggunakan 4 KiB, baki 4 KiB lagi kekal dan FD masih boleh dibaca; aplikasi tidak pernah memajukannya kepada "tiada lagi data sekarang." ET tidak menjanjikan laporan lain untuk keadaan yang tidak berubah itu, jadi menunggu peristiwa baharu boleh menyekat selama-lamanya.
Peraturan yang boleh dipercayai adalah dengan menganggap FD yang dikembalikan oleh ET sebagai sedia dan terus melaksanakan I/O tidak menyekat sehingga ia mengembalikan EAGAIN atau EWOULDBLOCK. Nilai-nilai tersebut bermaksud tiada operasi lanjut boleh membuat kemajuan pada masa ini tanpa menyekat. Hanya selepas itu aplikasi menyerahkan semula tanggungjawab pemberitahuan kepada epoll.
Langkah 3: Jadikan pembacaan sebagai mesin keadaan eksplisit
Lakaran seperti C ini mengetepikan butiran penghurai khusus aplikasi, jangka hayat, dan pengelogan:
void drain_read(Connection *conn) {
unsigned char buf[4096];
for (;;) {
ssize_t n = recv(conn->fd, buf, sizeof buf, 0);
if (n > 0) {
append_and_parse(conn, buf, (size_t)n);
continue;
}
if (n == 0) {
conn->peer_write_closed = true;
break;
}
if (errno == EINTR) {
continue;
}
if (errno == EAGAIN || errno == EWOULDBLOCK) {
break;
}
close_with_error(conn, errno);
return;
}
if (conn->peer_write_closed && output_is_empty(conn)) {
close_connection(conn);
}
}n > 0 hanya bermaksud bahawa bait tersebut telah tiba; penghurai mungkin masih kekurangan permintaan yang lengkap. n == 0 ialah penutupan rakan setara yang teratur pada soket aliran, selepas data yang telah ditimbal digunakan. EINTR boleh dicuba semula, EAGAIN/EWOULDBLOCK menyelesaikan pas pengosongan ini, dan ralat lain memasuki laluan tutup. Bacaan pendek bukan bukti penyempurnaan mesej atau soket kosong.
Soket pendengaran mengikut corak yang sama. Apabila boleh dibaca, gelung ke atas accept4, gunakan SOCK_NONBLOCK | SOCK_CLOEXEC secara atomik pada setiap sambungan baharu, sehingga EAGAIN. Menerima hanya satu sambungan boleh membiarkan sambungan lain yang telah beratur terkandas di bawah ET tanpa jaminan pemberitahuan kemudian.
Langkah 4: Kawal penimbalan output dan EPOLLOUT
Cuba hantar output bertimbal serta-merta. Pada send separa, majukan ofset dan teruskan. Cuba semula EINTR. Pada EAGAIN/EWOULDBLOCK, kekalkan bait yang tinggal dan tambahkan EPOLLOUT melalui EPOLL_CTL_MOD. Teruskan pengosongan pada peristiwa boleh ditulis seterusnya. Alih keluar EPOLLOUT daripada topeng minat sebaik sahaja penimbal output kosong.
Langganan EPOLLOUT yang kekal mencipta mod kegagalan yang berbeza: soket sering boleh ditulis untuk tempoh yang lama, jadi LT berulang kali kembali serta-merta dan CPU meningkat tanpa kemajuan perniagaan. ET tidak menghapuskan penimbal output aplikasi, tekanan balik (backpressure), had penimbal maksimum, atau dasar klien perlahan; ia hanya mengubah tingkah laku pemberitahuan.
Langkah 5: Kendalikan penutupan separuh, HUP, ERR, dan susunan penutupan
EPOLLRDHUP menunjukkan bahawa rakan setara aliran menutup sambungan atau bahagian tulisnya. EPOLLHUP menyatakan rakan setara menutup bahagian salurannya, tetapi data mungkin kekal belum dibaca; menutup serta-merta boleh membuangnya. EPOLLERR dan EPOLLHUP dilaporkan walaupun tidak diminta secara eksplisit. Pada ERR, getsockopt(SO_ERROR) boleh mendapatkan semula ralat soket yang belum selesai sebelum aplikasi merekod dan menutupnya mengikut dasar protokol.
Laluan tutup harus menghentikan kerja baharu daripada ditugaskan terlebih dahulu dan memastikan tugas tak segerak tidak dapat mengekalkan identiti yang telah tamat tempoh. Menutup FD terakhir yang merujuk kepada perihalan fail terbuka yang mendasari membolehkan kernel mengalih keluar pendaftaran. Jika dup atau fork berkongsi perihalan tersebut, menutup satu FD tidak semestinya menghapuskan peristiwa berkaitan serta-merta, jadi protokol pemilikan mesti secara eksplisit melakukan DEL pada entri atau menutup setiap rujukan. Gunakan objek sambungan dengan jangka hayat terkawal dan generasi atau token supaya penggunaan semula integer FD yang pantas tidak dapat mengubah hala kerja lama ke sambungan baharu.
Langkah 6: Gunakan EPOLLONESHOT untuk pemilikan pekerja
Beberapa bebenang boleh menunggu pada satu tika epoll. Untuk FD ET, kernel biasanya membangunkan satu penunggu apabila FD menjadi sedia, tetapi itu sahaja tidak menjadikan sambungan tersebut milik tunggal sepanjang pemprosesan. Kerja yang beratur dan peristiwa kemudian masih boleh mencipta akses serentak.
EPOLLONESHOT menyahdayakan FD selepas satu penghantaran peristiwa. Selepas mengosongkan I/O dan mengemas kini keadaan protokol serta topeng minat, pekerja yang mengekalkan sambungan tetap hidup memanggil epoll_ctl(EPOLL_CTL_MOD) untuk mempersiapkannya semula. Persiapan semula mestilah langkah penyerahan terakhir. Terlupa MOD akan menghentikan sambungan; melakukannya terlalu awal boleh membenarkan pekerja baharu masuk sebelum pemilik lama selesai.
Langkah 7: Kekalkan ketepatan dan keadilan ET bersama-sama
Mengosongkan sehingga EAGAIN boleh membiarkan sambungan yang sibuk secara berterusan menduduki bebenang dan melambatkan sambungan lain. Gelung boleh menguatkuasakan belanjawan bait, mesej, atau masa bagi setiap sambungan. Jika belanjawan tersebut tamat sebelum EAGAIN, ia tidak boleh kembali begitu sahaja dan menunggu kernel. Ia mesti menandakan sambungan sebagai boleh laksana dalam giliran sedia ruang pengguna dan menyambungnya semula kemudian sehingga ia mencapai EAGAIN.
Giliran harus menghalang entri pendua. Penutupan sambungan, pemindahan pekerja, dan persiapan semula EPOLLONESHOT mesti berkongsi protokol pemilikan yang sama. Ini mengekalkan kontrak ET tanpa membenarkan satu FD hangat membulurkan FD lain.
Langkah 8: Bina pengesahan yang mendedahkan pinggir yang hilang
Satu permintaan biasa sahaja tidak mencukupi. Lindungi sekurang-kurangnya:
- satu penulisan klien 8 KiB manakala pelayan sengaja membaca paling banyak 4 KiB bagi setiap panggilan, menunjukkan keadaan terhenti ET pra-pembetulan dan pengosongan pasca-pembetulan hingga
EAGAIN; - satu mesej aplikasi dibahagikan merentasi beberapa hantaran dengan jeda pada sempadan sewenang-wenangnya, membuktikan penghuraian adalah bebas daripada saiz satu
recv; - penghantaran pelayan terhad yang mencipta penulisan separa dan
EAGAIN, membuktikan tiada bait yang hilang danEPOLLOUTdialih keluar selepas pengosongan; - penutupan separuh rakan setara, HUP dengan data belum dibaca, set semula sambungan, dan
EINTR; - penghantaran
EPOLLONESHOTberulang dengan beberapa pekerja, membuktikan tepat satu pemilik dan persiapan semula bagi setiap sambungan hidup; - satu sambungan hangat yang menghantar berterusan ditambah banyak sambungan perlahan, memerhatikan keadilan, CPU, kelewatan gelung peristiwa, dan panjang giliran sedia;
- penciptaan dan penutupan sambungan yang pantas, membuktikan kerja yang tertangguh tidak boleh menyasarkan nombor FD yang digunakan semula.
Perhatikan sebab penamatan bagi setiap pas recv/send/accept4, kiraan EAGAIN, perubahan topeng minat, persiapan semula oneshot, giliran sedia aplikasi, belanjawan bagi setiap sambungan, kelewatan gelung peristiwa, dan sambungan yang tidak membuat kemajuan. Lulus bermakna bait dan keadaan protokol yang betul, tiada keadaan terhenti kekal, tiada gelung sibuk kosong, tiada pemilik serentak, dan tiada kebuluran berpanjangan bagi sambungan perlahan.
Contoh Jawapan yang Mantap
"Satu tika epoll mengekalkan senarai minat, dan epoll_wait mengembalikan peristiwa daripada senarai sedianya. Ia membekalkan kesediaan I/O, bukan mesej TCP lengkap atau penyempurnaan tak segerak. Nilai pulangan panggilan sistem memacu mesin keadaan sambungan.
LT kelihatan pulih di sini kerana selepas menggunakan 4 KiB, baki 4 KiB lagi kekal, jadi kesediaan baca masih wujud dan penantian seterusnya melaporkan FD itu semula. Dengan EPOLLET, FD tidak pernah kembali kepada keadaan tidak boleh dibaca. ET tidak menjanjikan pemberitahuan berulang untuk keadaan yang kekal benar, jadi menunggu selepas satu bacaan boleh terhenti selama-lamanya.
Saya akan menjadikan kedua-dua soket pendengaran dan bersambung sebagai tidak menyekat. Laluan accept melakukan gelung ke atas accept4 hingga EAGAIN. Laluan baca melakukan gelung ke atas recv hingga EAGAIN, menghantar bait positif kepada penghurai berperingkat (incremental), memperlakukan sifar sebagai penutupan separuh tulis rakan setara, mencuba semula EINTR, dan menutup pada ralat lain. Output mencuba send serta-merta dan mengekalkan ofset selepas penulisan separa. Ia memantau EPOLLOUT hanya selepas EAGAIN dengan data masih belum selesai dan mengalih keluarnya selepas pengosongan. HUP dikosongkan sebelum tutup, dan ERR didiagnosis dengan SO_ERROR.
Dengan beberapa pekerja, saya menetapkan satu pemilik bagi setiap sambungan dan boleh menggunakan EPOLLONESHOT: pekerja mempersiapkan semula dengan MOD hanya selepas pengosongan I/O, kemas kini keadaan, dan pengiraan topeng. Jika belanjawan keadilan menghentikan kerja sebelum EAGAIN, saya memasukkan sambungan ke dalam giliran sedia ruang pengguna yang dinyahduplikasi dan bukannya menunggu pinggir yang tidak wujud. Identiti sambungan membawa keadaan jangka hayat atau generasi untuk mengharungi penggunaan semula FD dengan selamat.
Saya akan menghasilkan semula dengan penulisan 8 KiB dan had bacaan 4 KiB, kemudian menambah penulisan separa, penutupan separuh, set semula, oneshot, berbilang pekerja, dan beban sambungan hangat. Pembetulan ini lulus apabila setiap pas pengendalian ET mencapai EAGAIN atau penutupan eksplisit, semua output dihantar, EPOLLOUT tidak berpusing, setiap sambungan oneshot yang hidup dipersiapkan semula, dan tiada sambungan kekal melahu atau kebuluran selama-lamanya."
Kesilapan Biasa
- Memperlakukan kesediaan sebagai mesej lengkap → TCP ialah aliran bait, dan satu
recvbukan mesej aplikasi → gunakan penghuraian berperingkat dan penimbal input berasingan. - Mengurangkan ET kepada "ia sentiasa memberitahu sekali" → beberapa perubahan boleh menghasilkan beberapa peristiwa; jaminan yang hilang ialah pengulangan untuk keadaan sedia yang tidak berubah → proses sehingga
EAGAIN. - Membaca sekali di bawah ET → input bertimbal kekal tanpa pinggir baharu → gelung ke atas
recvhinggaEAGAIN/EWOULDBLOCK. - Menggabungkan ET dengan soket menyekat → gelung pengosongan boleh menyekat dan membulurkan keseluruhan gelung peristiwa → tetapkan mod tidak menyekat sebelum pendaftaran.
- Menerima satu sambungan bagi setiap peristiwa pendengar → sambungan yang telah beratur mungkin tidak menerima pemberitahuan kemudian → gelung ke atas
accept4hinggaEAGAIN. - Sentiasa melanggan
EPOLLOUT→ soket yang biasanya boleh ditulis menyebabkan penantian terus kembali → langgan hanya dengan output yang belum selesai dan alih keluar selepas pengosongan. - Menutup serta-merta pada HUP → data yang belum dibaca mungkin kekal → habiskan melalui mesin keadaan baca, kemudian tutup mengikut keadaan EOF dan output.
- Terlupa untuk mempersiapkan semula
EPOLLONESHOT→ FD kekal dinyahdayakan dalam senarai minat → gunakanEPOLL_CTL_MODselepas kemas kini keadaan. - Berhenti untuk keadilan dan menunggu peristiwa ET yang lain → FD mungkin kekal sedia tanpa pinggir baharu → sambung semula daripada giliran sedia ruang pengguna.
- Menggunakan hanya integer FD sebagai identiti → sambungan baharu mungkin menggunakan semula nombor tersebut selepas penutupan → gunakan jangka hayat terkawal dan identiti yang mengandungi generasi.
- Mendakwa ET sememangnya lebih pantas → hasil bergantung pada nisbah aktif, panggilan sistem, kerja aplikasi, dan ketepatan pelaksanaan → ukur CPU, kependaman, pemprosesan (throughput), dan keadilan di bawah beban perwakilan.
Soalan Susulan dan Cara Menjawab
Susulan 1: Mengapakah recv yang pendek tidak membuktikan bahawa soket telah dikosongkan?
recv biasanya mengembalikan apa sahaja yang tersedia pada masa itu sehingga panjang yang diminta. Pensegmenan rangkaian, penjadualan, dan pemasaan penghantaran semuanya boleh menghasilkan bacaan pendek sementara lebih banyak bait tiba kemudian. Sempadan pengosongan ET ialah EAGAIN/EWOULDBLOCK tidak menyekat; sempadan mesej aplikasi datang daripada penghurai protokol. Itu adalah sempadan yang berbeza.
Susulan 2: Adakah ET sentiasa lebih pantas daripada LT?
Mod itu sendiri tidak dapat menjawabnya. ET boleh mengurangkan pemberitahuan berulang untuk FD yang sedia berterusan, tetapi ia menambah kerumitan pengosongan, giliran ruang pengguna, dan pengurusan keadaan. Apabila kebanyakan sambungan tidak aktif, kerja aplikasi mendominasi, atau pelaksanaan menambah banyak panggilan epoll_ctl, keuntungannya mungkin kecil. Ukur CPU, panggilan sistem, daya pemprosesan, p99, dan keadilan pada kiraan sambungan sasaran dan taburan aktiviti, dengan mengutamakan ketepatan.
Susulan 3: Mengapa perlu mengalih keluar EPOLLOUT selepas penimbal output dikosongkan?
Boleh ditulis biasanya bermaksud penimbal hantar kernel boleh menerima sekurang-kurangnya beberapa bait, keadaan yang kekal benar untuk banyak sambungan. Memerhatikannya tanpa output aplikasi yang belum selesai menghasilkan pemberitahuan yang tidak berguna dan boleh mencipta gelung sibuk LT. Perhatikan penulisan hanya semasa bait masih kekal; apabila output aplikasi baharu muncul kemudian, cuba send serta-merta sebelum melanggan semula.
Susulan 4: Adakah EPOLLONESHOT dan ET ciri yang sama?
Tidak. EPOLLET mengubah tingkah laku pemberitahuan kesediaan. EPOLLONESHOT menyahdayakan FD selepas satu penghantaran peristiwa sehingga aplikasi mempersiapkannya semula dengan EPOLL_CTL_MOD. Ia boleh digabungkan. ONESHOT membantu memindahkan pemilikan pekerja, tetapi ET masih memerlukan pengosongan yang betul dan aplikasi masih memerlukan protokol persiapan semula.
Susulan 5: Belanjawan keadilan tamat sebelum EAGAIN; bagaimanakah anda mengelak daripada kehilangan peristiwa tersebut?
Tandakan sambungan sebagai masih boleh laksana dalam ruang pengguna dan letakkannya dalam giliran sedia yang dinyahduplikasi. Penjadual menyambung semula recv/send sehingga EAGAIN, penutupan, atau penamatan belanjawan yang lain. Kekalkan pemilik yang sah semasa beratur. Dengan ONESHOT, persiapkan semula hanya selepas kerja ruang pengguna selesai dan sambungan memerlukan pemberitahuan kernel semula.
Susulan 6: Mengapa perlu bimbang tentang peristiwa lama selepas menutup FD?
Satu kelompok peristiwa mungkin sudah berada dalam ruang pengguna, dan pekerja tak segerak mungkin mengekalkan rujukan sambungan manakala kernel dengan cepat memberikan integer yang sama kepada soket baharu. Berbilang FD juga boleh merujuk kepada satu perihalan fail terbuka. Laluan penutupan mesti menghentikan penghantaran baharu, mengurus jangka hayat objek, dan membatalkan token lama. Membandingkan integer FD sahaja tidak dapat membuktikan peristiwa itu milik sambungan semasa.