Teknik pengoptimuman multithreading dalam C++
Dengan perkembangan teknologi komputer dan peningkatan prestasi perkakasan, teknologi multi-threading telah menjadi kemahiran penting untuk pengaturcaraan moden. C++ ialah bahasa pengaturcaraan klasik yang turut menyediakan banyak teknologi multi-threading yang berkuasa. Artikel ini akan memperkenalkan beberapa teknik pengoptimuman berbilang benang dalam C++ untuk membantu pembaca menggunakan teknologi berbilang benang dengan lebih baik.
1. Gunakan std::thread
C++11 memperkenalkan std::thread, yang secara langsung menyepadukan teknologi multi-threading ke dalam perpustakaan standard. Mencipta utas baharu menggunakan std::thread adalah sangat mudah, hanya lulus penunjuk fungsi. Contohnya:
#include <thread> #include <iostream> void hello() { std::cout << "Hello World!"; } int main() { std::thread t(hello); t.join(); return 0; }
Kod di atas mencipta utas t baharu, melaksanakan fungsi helo dan menunggu utas t selesai. Ambil perhatian bahawa penciptaan dan pemusnahan benang memerlukan jumlah overhed tertentu, jadi std::thread perlu digunakan secara rasional.
2. Gunakan std::async
std::async ialah satu lagi teknologi berbilang benang yang mudah digunakan. Gunakan std::async untuk mengurus perlaksanaan tugas tak segerak dan mendapatkan hasil dengan lebih mudah. Contohnya:
#include <future> #include <iostream> int add(int a, int b) { return a + b; } int main() { auto async_result = std::async(add, 1, 2); std::cout << async_result.get(); return 0; }
Kod di atas memanggil fungsi tambah untuk mengira 1+2 secara tak segerak dan menggunakan objek std::depan untuk mengurus perolehan hasil pengiraan. Perlu diingat bahawa std::async menggunakan strategi std::launch::async secara lalai dan akan melaksanakan fungsi dalam urutan baharu. Jika anda ingin menggunakan strategi std::launch::deferred, anda perlu menentukannya secara manual. Walau bagaimanapun, menggunakan strategi std::launch::deferred akan menyebabkan fungsi dilaksanakan hanya apabila std::future::get() dipanggil, jadi pilihan perlu dibuat berdasarkan kes demi kes.
3. Gunakan std::condition_variable
Dalam pengaturcaraan multi-thread, komunikasi dan penyegerakan perlu dijalankan antara thread, dan std::condition_variable boleh mencapai tujuan ini dengan baik. Menggunakan std::condition_variable membenarkan satu utas menunggu keadaan tertentu bagi utas lain menjadi benar, dengan itu mencapai penyegerakan antara utas. Contohnya:
#include <condition_variable> #include <mutex> #include <thread> #include <iostream> std::mutex mutex; std::condition_variable cv; bool ready = false; void producer() { std::unique_lock<std::mutex> lock(mutex); // wait for the condition to become true cv.wait(lock, [] { return ready; }); std::cout << "Producer done." << std::endl; } void consumer() { std::this_thread::sleep_for(std::chrono::seconds(1)); ready = true; std::cout << "Consumer done." << std::endl; cv.notify_one(); } int main() { std::thread t1(producer); std::thread t2(consumer); t1.join(); t2.join(); return 0; }
Kod di atas mencipta dua utas t1 dan t2, di mana t1 menunggu sehingga pembolehubah keadaan sedia menjadi benar, manakala t2 menetapkan pembolehubah keadaan kepada benar selepas menunggu selama 1 saat dan memberitahu t1. Perlu diingat bahawa std::condition_variable mesti digunakan bersama dengan std::mutex untuk menghalang berbilang benang daripada mengakses pembolehubah keadaan pada masa yang sama.
4. Gunakan kumpulan benang
Dalam kes sejumlah besar tugasan jangka pendek yang perlu dibuat dan dijalankan, kumpulan benang sering digunakan untuk meningkatkan prestasi program. Kumpulan benang mengekalkan bilangan benang tertentu dan mengurus peruntukan dan pelaksanaan tugas. Menggunakan kumpulan benang boleh mengelakkan overhed tambahan untuk kerap mencipta dan memusnahkan benang, sambil memanfaatkan sepenuhnya CPU berbilang teras. Contohnya:
#include <iostream> #include <thread> #include <mutex> #include <condition_variable> #include <vector> #include <queue> #include <functional> class ThreadPool { public: ThreadPool(std::size_t numThreads = std::thread::hardware_concurrency()) { for (std::size_t i = 0; i < numThreads; ++i) { pool.emplace_back([this] { while (!stop) { std::function<void()> task; { std::unique_lock<std::mutex> lock{ mutex }; condition.wait(lock, [this] { return stop || !tasks.empty(); }); if (stop && tasks.empty()) return; task = std::move(tasks.front()); tasks.pop(); } task(); } }); } } ~ThreadPool() { { std::unique_lock<std::mutex> lock{ mutex }; stop = true; } condition.notify_all(); for (auto& worker : pool) { worker.join(); } } template <typename F, typename... Args> auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> { using return_type = typename std::result_of<F(Args...)>::type; auto task = std::make_shared<std::packaged_task<return_type()>>( std::bind(std::forward<F>(f), std::forward<Args>(args)...)); std::future<return_type> future = task->get_future(); { std::unique_lock<std::mutex> lock{ mutex }; if (stop) throw std::runtime_error("enqueue on stopped ThreadPool"); tasks.emplace([task](){ (*task)(); }); } condition.notify_one(); return future; } private: std::vector<std::thread> pool; std::queue<std::function<void()>> tasks; std::mutex mutex; std::condition_variable condition; bool stop = false; }; void hello() { std::cout << "Hello World!" << std::endl; } int add(int a, int b) { return a + b; } int main() { { ThreadPool pool; auto f1 = pool.enqueue(hello); auto f2 = pool.enqueue(add, 1, 2); std::cout << f2.get() << std::endl; } return 0; }
Kod di atas mentakrifkan kelas ThreadPool, yang mengandungi berbilang urutan dan baris gilir tugas. Kumpulan benang terus mengambil tugasan daripada baris gilir tugas dan melaksanakannya sehingga baris gilir kosong atau kumpulan benang berhenti. Gunakan kaedah ThreadPool::enqueue untuk menambah tugasan pada baris gilir tugas dan mengembalikan objek std::depan untuk mengurus hasil pelaksanaan tugas.
Secara umumnya, C++ menyediakan pelbagai teknologi berbilang benang untuk membantu pembangun memanfaatkan prestasi CPU berbilang teras dan mengurus urutan serta tugasan dengan lebih fleksibel. Pembangun harus menggunakan teknik ini dengan sewajarnya untuk mengoptimumkan prestasi program.
Atas ialah kandungan terperinci Teknik pengoptimuman multithreading dalam C++. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Langkah-langkah untuk melaksanakan corak strategi dalam C++ adalah seperti berikut: tentukan antara muka strategi dan isytiharkan kaedah yang perlu dilaksanakan. Buat kelas strategi khusus, laksanakan antara muka masing-masing dan sediakan algoritma yang berbeza. Gunakan kelas konteks untuk memegang rujukan kepada kelas strategi konkrit dan melaksanakan operasi melaluinya.

Pengendalian pengecualian bersarang dilaksanakan dalam C++ melalui blok try-catch bersarang, membenarkan pengecualian baharu dibangkitkan dalam pengendali pengecualian. Langkah-langkah cuba-tangkap bersarang adalah seperti berikut: 1. Blok cuba-tangkap luar mengendalikan semua pengecualian, termasuk yang dilemparkan oleh pengendali pengecualian dalam. 2. Blok cuba-tangkap dalam mengendalikan jenis pengecualian tertentu, dan jika pengecualian luar skop berlaku, kawalan diberikan kepada pengendali pengecualian luaran.

Warisan templat C++ membenarkan kelas terbitan templat menggunakan semula kod dan kefungsian templat kelas asas, yang sesuai untuk mencipta kelas dengan logik teras yang sama tetapi gelagat khusus yang berbeza. Sintaks warisan templat ialah: templateclassDerived:publicBase{}. Contoh: templateclassBase{};templateclassDerived:publicBase{};. Kes praktikal: Mencipta kelas terbitan Derived, mewarisi fungsi mengira Base kelas asas, dan menambah kaedah printCount untuk mencetak kiraan semasa.

Dalam C, jenis char digunakan dalam rentetan: 1. Simpan satu watak; 2. Gunakan array untuk mewakili rentetan dan berakhir dengan terminator null; 3. Beroperasi melalui fungsi operasi rentetan; 4. Baca atau output rentetan dari papan kekunci.

Punca dan penyelesaian untuk kesilapan Apabila menggunakan PECL untuk memasang sambungan dalam persekitaran Docker Apabila menggunakan persekitaran Docker, kami sering menemui beberapa sakit kepala ...

Dalam C++ berbilang benang, pengendalian pengecualian dilaksanakan melalui mekanisme std::promise dan std::future: gunakan objek promise untuk merekodkan pengecualian dalam utas yang membuang pengecualian. Gunakan objek masa hadapan untuk menyemak pengecualian dalam urutan yang menerima pengecualian. Kes praktikal menunjukkan cara menggunakan janji dan niaga hadapan untuk menangkap dan mengendalikan pengecualian dalam urutan yang berbeza.

Multithreading dalam bahasa dapat meningkatkan kecekapan program. Terdapat empat cara utama untuk melaksanakan multithreading dalam bahasa C: Buat proses bebas: Buat pelbagai proses berjalan secara bebas, setiap proses mempunyai ruang ingatan sendiri. Pseudo-Multithreading: Buat pelbagai aliran pelaksanaan dalam proses yang berkongsi ruang memori yang sama dan laksanakan secara bergantian. Perpustakaan multi-threaded: Gunakan perpustakaan berbilang threaded seperti PTHREADS untuk membuat dan mengurus benang, menyediakan fungsi operasi benang yang kaya. Coroutine: Pelaksanaan pelbagai threaded ringan yang membahagikan tugas menjadi subtask kecil dan melaksanakannya pada gilirannya.

Pengiraan C35 pada dasarnya adalah matematik gabungan, yang mewakili bilangan kombinasi yang dipilih dari 3 dari 5 elemen. Formula pengiraan ialah C53 = 5! / (3! * 2!), Yang boleh dikira secara langsung oleh gelung untuk meningkatkan kecekapan dan mengelakkan limpahan. Di samping itu, memahami sifat kombinasi dan menguasai kaedah pengiraan yang cekap adalah penting untuk menyelesaikan banyak masalah dalam bidang statistik kebarangkalian, kriptografi, reka bentuk algoritma, dll.
