


C multithreading and concurrency: Menguasai pengaturcaraan selari
C Konsep teras pengaturcaraan multithreading dan serentak termasuk penciptaan dan pengurusan thread, penyegerakan dan pengecualian bersama, pembolehubah bersyarat, penyatuan thread, pengaturcaraan tak segerak, kesilapan umum dan teknik debugging, dan pengoptimuman prestasi dan amalan terbaik. 1) Buat benang menggunakan kelas STD :: Thread. Contohnya menunjukkan cara membuat dan menunggu benang selesai. 2) Segerakkan dan pengecualian bersama untuk menggunakan std :: mutex dan std :: lock_guard untuk melindungi sumber bersama dan mengelakkan persaingan data. 3) Pemboleh ubah keadaan menyedari komunikasi dan penyegerakan antara benang melalui std :: condition_variable. 4) Contoh kolam benang menunjukkan cara menggunakan kelas threadpool untuk memproses tugas selari untuk meningkatkan kecekapan. 5) Pengaturcaraan Asynchronous dilaksanakan menggunakan STD :: Async dan STD :: Masa Depan. Contohnya menunjukkan permulaan dan pengambilalihan hasil tugas tak segerak. 6) Kesilapan umum termasuk persaingan data, kebuntuan dan kebocoran sumber, kemahiran debugging termasuk menggunakan kunci dan operasi atom, dan alat debugging. 7) Cadangan Pengoptimuman Prestasi termasuk penggunaan kolam thread, STD :: penggunaan kunci atom dan munasabah untuk meningkatkan prestasi program dan keselamatan.
Pengenalan
Dalam pengaturcaraan moden, pengaturcaraan multithreading dan serentak telah menjadi teknologi utama untuk meningkatkan prestasi program dan respons. Sama ada anda sedang membangunkan aplikasi pengkomputeran berprestasi tinggi atau membina antara muka pengguna yang responsif, menguasai pengaturcaraan multi-threading dan serentak dalam C adalah kemahiran penting. Artikel ini akan membawa anda ke dalam pemahaman yang mendalam tentang konsep teras dan teknik praktikal C multithreading dan pengaturcaraan serentak, membantu anda menjadi tuan pengaturcaraan selari.
Dengan membaca artikel ini, anda akan belajar bagaimana untuk membuat dan mengurus benang, memahami mekanisme penyegerakan dan pengecualian bersama dalam pengaturcaraan serentak, dan bagaimana untuk mengelakkan perangkap pengaturcaraan serentak yang sama. Sama ada anda seorang pemula atau pemaju yang berpengalaman, anda boleh mendapat manfaat daripadanya.
Semak pengetahuan asas
Sebelum menyelam ke pengaturcaraan multithreading dan serentak, mari kita semak beberapa asas terlebih dahulu. Standard C 11 memperkenalkan perpustakaan <thread></thread>
, membuat penciptaan dan menguruskan benang dalam C lebih mudah dan lebih intuitif. Di samping itu, perpustakaan seperti <mutex></mutex>
, <condition_variable></condition_variable>
dan <atomic></atomic>
menyediakan alat yang diperlukan untuk mengendalikan penyegerakan dan komunikasi antara benang.
Memahami konsep asas ini adalah penting untuk menguasai pengaturcaraan pelbagai threaded. Sebagai contoh, benang adalah unit penjadualan sistem operasi terkecil, manakala mutexes digunakan untuk melindungi sumber bersama dan mencegah persaingan data.
Konsep teras atau analisis fungsi
Penciptaan dan pengurusan benang
Dalam C, membuat benang sangat mudah, hanya gunakan kelas std::thread
. Berikut adalah contoh mudah:
#include <iostream> #Enclude <Hreat> void thread_function () { std :: cout << "Hello dari thread!" << std :: endl; } int main () { std :: thread t (thread_function); t.join (); kembali 0; }
Contoh ini menunjukkan cara membuat benang dan menunggu ia selesai. Kaedah join()
menghalang benang utama sehingga benang kanak -kanak melengkapkan pelaksanaan.
Penyegerakan dan pengecualian bersama
Dalam pengaturcaraan multithreaded, penyegerakan dan pengecualian bersama adalah kunci untuk mengelakkan persaingan data. std::mutex
dan std::lock_guard
adalah alat yang biasa digunakan. Berikut adalah contoh menggunakan mutex untuk melindungi sumber bersama:
#include <iostream> #Enclude <Hreat> #include <mutex> std :: mutex mtx; int shared_data = 0; void kenaikan () { untuk (int i = 0; i <100000; i) { std :: lock_guard <std :: mutex> lock (mtx); Shared_data; } } int main () { std :: Thread T1 (kenaikan); std :: Thread T2 (kenaikan); t1.join (); t2.join (); std :: cout << "Nilai akhir shared_data:" << shared_data << std :: endl; kembali 0; }
Dalam contoh ini, std::lock_guard
memastikan bahawa mutex dikunci dan dikunci dengan betul apabila mengakses shared_data
, mengelakkan persaingan data.
Pembolehubah bersyarat
Pembolehubah keadaan adalah satu lagi mekanisme penyegerakan penting yang digunakan untuk komunikasi antara benang. Berikut adalah contoh menggunakan pembolehubah bersyarat:
#include <iostream> #Enclude <Hreat> #include <mutex> #Enclude <davition_variable> std :: mutex mtx; STD :: CONDITE_VARIABLE CV; bool siap = palsu; void print_id (int id) { std :: unik_lock <std :: mutex> lck (mtx); sementara (! siap) cv.wait (LCK); std :: cout << "thread" << id << std :: endl; } void go () { std :: unik_lock <std :: mutex> lck (mtx); siap = benar; cv.notify_all (); } int main () { Std :: Thread Threads [10]; untuk (int i = 0; i <10; i) { Threads [i] = std :: thread (print_id, i); } std :: cout << "10 threads siap untuk berlumba ..." << std :: endl; pergi (); untuk (auto & th: threads) th.join (); kembali 0; }
Dalam contoh ini, cv
pembolehubah keadaan digunakan untuk memberitahu semua benang menunggu untuk memulakan pelaksanaan.
Contoh penggunaan
Penggunaan asas
Mewujudkan dan menguruskan benang adalah asas pengaturcaraan pelbagai threaded. Berikut adalah contoh yang lebih kompleks yang menunjukkan cara menggunakan kolam benang untuk memproses tugas secara selari:
#include <iostream> #include <vector> #Enclude <Hreat> #Enclude <SIRILE> #include <mutex> #Enclude <davition_variable> #Enclude <Fticeal> kelas threadpool { awam: ThreadPool (Size_t Threads): berhenti (palsu) { untuk (size_t i = 0; i <threads; i) { pekerja.emplace_back ([ini] { sementara (benar) { std :: fungsi <void ()> tugas; { std :: unik_lock <std :: mutex> lock (queue_mutex); condition.wait (kunci, [this] {return stop || tasks.empty ();}); jika (stop && tugas.empty ()) kembali; tugas = std :: bergerak (tugas.front ()); tugas.pop (); } tugas (); } }); } } templat <kelas f, kelas ... args> Auto Enqueue (f && f, args && ... args) -> std :: masa depan <typename std :: result_of <f (args ...)> :: type> { menggunakan return_type = typename std :: result_of <f (args ...)> :: type; tugas auto = std :: make_shared <std :: packaged_task <return_type () >> ( std :: bind (std :: forward <f> (f), std :: forward <args> (args) ...) ); STD :: Masa Depan <nackR_Type> res = task-> get_future (); { std :: unik_lock <std :: mutex> lock (queue_mutex); jika (berhenti) lemparkan std :: runtime_error ("enqueue pada threadpool berhenti"); tugas.emplace ([tugas] () {(*tugas) ();}); } keadaan.notify_one (); kembali res; } ~ Threadpool () { { std :: unik_lock <std :: mutex> lock (queue_mutex); berhenti = benar; } condition.notify_all (); untuk (std :: thread & worker: pekerja) worker.join (); } Swasta: std :: vektor <std :: thread> pekerja; std :: giliran <std :: fungsi <void () >> tugas; std :: mutex queue_mutex; STD :: Condition_variable Condition; Bool berhenti; }; int main () { Kolam Renang Threadpool (4); std :: vector <std :: future <int >> hasil; untuk (int i = 0; i <8; i) { hasil.emplace_back ( pool.enqueue ([i] { kembali i * i; }) ); } untuk (auto && hasil: hasil) { std :: cout << result.get () << ''; } std :: cout << std :: endl; kembali 0; }
Contoh ini menunjukkan cara menggunakan kolam thread untuk memproses tugas selari, meningkatkan kesesuaian program dan kecekapan.
Penggunaan lanjutan
Dalam aplikasi praktikal, senario pengaturcaraan serentak yang lebih kompleks boleh ditemui. Sebagai contoh, gunakan std::async
dan std::future
untuk melaksanakan pengaturcaraan tak segerak:
#include <iostream> #Enclude <Petera> #include <chrono> int main () { Auto Future = std :: async (std :: launch :: async, [] { std :: this_thread :: sleep_for (std :: chrono :: saat (2)); pulangan 42; }); std :: cout << "Menunggu hasil ..." << std :: endl; int result = future.get (); std :: cout << "hasil:" << hasil << std :: endl; kembali 0; }
Dalam contoh ini, std::async
digunakan untuk memulakan tugas yang tidak segerak, std::future
digunakan untuk mendapatkan hasil tugas.
Kesilapan biasa dan tip debugging
Kesalahan biasa dalam pengaturcaraan multithread termasuk perlumbaan data, kebuntuan, dan kebocoran sumber. Berikut adalah beberapa petua debug:
- Gunakan
std::lock_guard
danstd::unique_lock
untuk memastikan penggunaan mutexes yang betul dan elakkan kebuntuan. - Gunakan
std::atomic
untuk mengendalikan pembolehubah bersama dan elakkan persaingan data. - Gunakan alat penyahpepijatan seperti Valgrind atau AlamatSanitizer untuk mengesan kebocoran memori dan persaingan data.
Pengoptimuman prestasi dan amalan terbaik
Dalam aplikasi praktikal, adalah penting untuk mengoptimumkan prestasi program berbilang threaded. Berikut adalah beberapa petua pengoptimuman dan amalan terbaik:
- Elakkan penciptaan dan kemusnahan benang yang berlebihan dan gunakan kolam benang untuk menguruskan benang.
- Gunakan
std::atomic
untuk meningkatkan kecekapan akses pembolehubah yang dikongsi. - Gunakan kunci dengan munasabah untuk mengurangkan granulariti kunci dan elakkan persaingan kunci.
Sebagai contoh, inilah contoh menggunakan std::atomic
untuk mengoptimumkan akses kepada pembolehubah yang dikongsi:
#include <iostream> #Enclude <Hreat> #include <atomic> std :: atom <int> shared_data (0); void kenaikan () { untuk (int i = 0; i <100000; i) { Shared_data; } } int main () { std :: Thread T1 (kenaikan); std :: Thread T2 (kenaikan); t1.join (); t2.join (); std :: cout << "Nilai akhir shared_data:" << shared_data << std :: endl; kembali 0; }
Dalam contoh ini, menggunakan std::atomic
untuk memastikan operasi atom pembolehubah yang dikongsi meningkatkan prestasi dan keselamatan program.
Singkatnya, pengaturcaraan multithreading dan serentak adalah teknik yang kompleks tetapi sangat berguna. Melalui kajian artikel ini, anda sepatutnya menguasai konsep dan teknik teras seperti membuat dan mengurus benang, penyegerakan dan pengecualian bersama, dan pengoptimuman prestasi. Saya harap pengetahuan ini dapat membantu anda memohon pengaturcaraan berbilang thread yang lebih baik dalam projek-projek sebenar dan meningkatkan prestasi program dan respons.
Atas ialah kandungan terperinci C multithreading and concurrency: Menguasai pengaturcaraan selari. 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



Dalam pengaturcaraan serentak C++, reka bentuk struktur data yang selamat serentak adalah penting: Bahagian kritikal: Gunakan kunci mutex untuk mencipta blok kod yang membenarkan hanya satu utas untuk dilaksanakan pada masa yang sama. Kunci baca-tulis: membenarkan beberapa utas dibaca pada masa yang sama, tetapi hanya satu utas untuk ditulis pada masa yang sama. Struktur data tanpa kunci: Gunakan operasi atom untuk mencapai keselamatan serentak tanpa kunci. Kes praktikal: Barisan selamat benang: Gunakan bahagian kritikal untuk melindungi operasi baris gilir dan mencapai keselamatan benang.

Penjadualan tugas dan pengurusan kumpulan benang adalah kunci untuk meningkatkan kecekapan dan kebolehskalaan dalam pengaturcaraan serentak C++. Penjadualan tugas: Gunakan std::thread untuk membuat thread baharu. Gunakan kaedah join() untuk menyertai utas. Pengurusan kolam benang: Buat objek ThreadPool dan nyatakan bilangan utas. Gunakan kaedah add_task() untuk menambah tugas. Panggil kaedah join() atau stop() untuk menutup kumpulan benang.

Mekanisme dipacu peristiwa dalam pengaturcaraan serentak bertindak balas kepada peristiwa luaran dengan melaksanakan fungsi panggil balik apabila peristiwa berlaku. Dalam C++, mekanisme dipacu peristiwa boleh dilaksanakan dengan penunjuk fungsi: penunjuk fungsi boleh mendaftarkan fungsi panggil balik untuk dilaksanakan apabila peristiwa berlaku. Ungkapan Lambda juga boleh melaksanakan panggilan balik acara, membenarkan penciptaan objek fungsi tanpa nama. Kes sebenar menggunakan penunjuk fungsi untuk melaksanakan peristiwa klik butang GUI, memanggil fungsi panggil balik dan mencetak mesej apabila peristiwa itu berlaku.

Kaedah untuk komunikasi antara benang dalam C++ termasuk: memori dikongsi, mekanisme penyegerakan (kunci mutex, pembolehubah keadaan), paip dan baris gilir mesej. Contohnya, gunakan kunci mutex untuk melindungi pembilang yang dikongsi: mengisytiharkan kunci mutex (m) dan pembolehubah yang dikongsi (pembilang); untuk mengelakkan keadaan perlumbaan.

Untuk mengelakkan kebuluran benang, anda boleh menggunakan kunci yang adil untuk memastikan peruntukan sumber yang adil, atau menetapkan keutamaan benang. Untuk menyelesaikan penyongsangan keutamaan, anda boleh menggunakan warisan keutamaan, yang meningkatkan keutamaan utas yang memegang sumber buat sementara waktu atau menggunakan promosi kunci, yang meningkatkan keutamaan utas yang memerlukan sumber.

Dalam pengaturcaraan berbilang benang C++, peranan primitif penyegerakan adalah untuk memastikan ketepatan berbilang utas yang mengakses sumber yang dikongsi Ia termasuk: Mutex (Mutex): melindungi sumber yang dikongsi dan menghalang akses serentak (ConditionVariable): thread Tunggu khusus syarat yang perlu dipenuhi sebelum meneruskan operasi atom: memastikan bahawa operasi dilaksanakan dengan cara yang tidak terganggu.

Mekanisme penamatan dan pembatalan utas dalam C++ termasuk: Penamatan utas: std::thread::join() menyekat utas semasa sehingga utas sasaran menyelesaikan pelaksanaan std::thread::detach() menanggalkan utas sasaran daripada pengurusan utas. Pembatalan utas: std::thread::request_termination() meminta utas sasaran untuk menamatkan pelaksanaan; benang. Dalam pertempuran sebenar, request_termination() membenarkan utas untuk menentukan masa penamatan, dan join() memastikan bahawa pada baris utama

Rangka kerja pengaturcaraan serentak C++ menampilkan pilihan berikut: utas ringan (std::benang-benang Boost concurrency concurrency dan algoritma OpenMP untuk pemproses berbilang pemproses berprestasi tinggi (TBB); (cpp-Setuju).
