Dalam persekitaran berbilang benang, adalah penting untuk memastikan bahagian kod yang kritikal dilindungi untuk mengelakkan rasuah data. Satu bahagian kritikal tersebut ialah pengurusan baris gilir data. Baris gilir ialah struktur data yang mengikut prinsip "Masuk Pertama, Keluar Dahulu" (FIFO). Melaksanakan baris gilir selamat benang dalam C 11 melibatkan penggunaan mekanisme penyegerakan seperti muteks dan pembolehubah keadaan.
Coretan kod yang dimaksudkan mempersembahkan baris gilir selamat benang menggunakan std::mutex dan std::condition_variable. Kaedah enqueue menambah item pada baris gilir sambil memegang kunci pada qMutex untuk melindungi baris gilir. Ia juga memberitahu mana-mana urutan menunggu menggunakan pembolehubah keadaan populatedNotifier.
Kaedah dequeue mendapatkan semula item daripada baris gilir. Ia memperoleh kunci unik pada qMutex, menyemak sama ada baris gilir kosong, dan menunggu menggunakan fungsi wait_for dengan tamat masa jika perlu. Jika urutan dimaklumkan tentang item baharu dalam baris gilir, ia akan keluar dari menunggu dan meneruskan untuk mendapatkan dan mengalih keluar item daripada baris gilir.
Walau bagaimanapun, segfaults diperhatikan apabila baris gilir kosong, menunjukkan fungsi wait_for dikembalikan tanpa pemberitahuan. Ini mungkin berlaku disebabkan oleh bangun tidur palsu.
Untuk mengelakkan isu ini, dinasihatkan untuk menyongsangkan keadaan untuk gelung sementara. Daripada "menunggu baris gilir tidak kosong," tunggu sementara "baris gilir kosong." Ini memastikan bahawa gelung menyemak semula kekosongan baris gilir selepas sebarang bangun yang palsu.
Berikut ialah versi semakan kaedah dequeue:
<code class="cpp">std::string FileQueue::dequeue(const std::chrono::milliseconds& timeout) { std::unique_lock<std::mutex> lock(qMutex); while (q.empty()) { if (populatedNotifier.wait_for(lock, timeout) == std::cv_status::no_timeout) { // Lock may have been released spuriously; recheck condition if (q.empty()) { return std::string(); } std::string ret = q.front(); q.pop(); return ret; } else { return std::string(); } } std::string ret = q.front(); q.pop(); return ret; }</code>
Ini memastikan urutan hanya diteruskan apabila baris gilir tidak kosong, mengelakkan segfault yang disebabkan oleh bangun tidur palsu.
Atas ialah kandungan terperinci Bagaimana untuk Mencegah Segfaults dalam Baris Gilir Selamat Benang C 11 Apabila Menggunakan `std::condition_variable::wait_for`?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!