Masalah penyegerakan berbilang benang dan penyelesaian dalam C++

WBOY
Lepaskan: 2023-10-09 17:32:10
asal
1232 orang telah melayarinya

Masalah penyegerakan berbilang benang dan penyelesaian dalam C++

Masalah dan penyelesaian penyegerakan berbilang benang dalam C++

Pengaturcaraan berbilang benang ialah satu cara untuk meningkatkan prestasi dan kecekapan program, tetapi ia juga membawa satu siri masalah penyegerakan. Dalam pengaturcaraan berbilang benang, berbilang benang boleh mengakses dan mengubah suai sumber data yang dikongsi pada masa yang sama, yang boleh membawa kepada keadaan perlumbaan data, kebuntuan, kelaparan dan masalah lain. Untuk mengelakkan masalah ini, kita perlu menggunakan mekanisme penyegerakan untuk memastikan kerjasama dan akses yang saling eksklusif antara rangkaian.

Dalam C++, kami boleh menggunakan pelbagai mekanisme penyegerakan untuk menyelesaikan masalah penyegerakan antara benang, termasuk kunci mutex, pembolehubah keadaan dan operasi atom. Di bawah kita akan membincangkan masalah penyegerakan biasa dan memberikan penyelesaian yang sepadan serta contoh kod.

1. Syarat pertandingan
Syarat pertandingan merujuk kepada berbilang rangkaian yang mengakses sumber yang dikongsi pada masa yang sama Disebabkan oleh ketidakpastian urutan akses, hasil pelaksanaan program tidak pasti. Untuk mengelakkan keadaan perlumbaan, kita perlu menggunakan kunci mutex untuk melindungi sumber yang dikongsi dan memastikan bahawa hanya satu utas boleh mengakses dan mengubah suai sumber yang dikongsi.

Berikut ialah contoh kod menggunakan kunci mutex untuk menyelesaikan masalah keadaan perlumbaan:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;
int counter = 0;

void increment() {
    std::lock_guard<std::mutex> lock(mtx);
    counter++;
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);

    t1.join();
    t2.join();

    std::cout << "Counter: " << counter << std::endl;

    return 0;
}
Salin selepas log masuk

Dalam kod di atas, kami menggunakan std::mutex untuk mencipta kunci mutex mtx, dan kemudian gunakan std::lock_guard untuk mengunci mutex bagi memastikan hanya satu utas boleh melakukan operasi pembilang++. Ini memastikan bahawa hasil pembilang ditakrifkan dengan betul.

2. Kebuntuan
Kebuntuan bermakna dua atau lebih utas sedang menunggu antara satu sama lain untuk melepaskan sumber, menyebabkan program tidak dapat meneruskan pelaksanaan. Untuk mengelakkan kebuntuan, kita boleh menggunakan teknologi RAII (pemerolehan sumber adalah permulaan) dan mengelakkan menunggu berbilang kunci dan kaedah lain.

Berikut adalah contoh untuk mengelakkan kebuntuan:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx1, mtx2;

void thread1() {
    std::unique_lock<std::mutex> lock1(mtx1);
    std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 延迟10毫秒,让线程2有足够时间锁住mtx2
    std::unique_lock<std::mutex> lock2(mtx2);
    
    // 访问共享资源
    std::cout << "Thread 1" << std::endl;
}

void thread2() {
    std::unique_lock<std::mutex> lock2(mtx2);
    std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 延迟10毫秒,让线程1有足够时间锁住mtx1
    std::unique_lock<std::mutex> lock1(mtx1);
    
    // 访问共享资源
    std::cout << "Thread 2" << std::endl;
}

int main() {
    std::thread t1(thread1);
    std::thread t2(thread2);

    t1.join();
    t2.join();

    return 0;
}
Salin selepas log masuk

Dalam kod di atas, kami menggunakan std::unique_lock dan bukannya std::lock_guard, supaya kunci boleh dikawal secara manual Dapatkan dan lepaskan. Kebuntuan dielakkan dengan mengunci satu mutex dan kemudian satu lagi dalam setiap benang.

3. Lapar
Lapar merujuk kepada situasi di mana benang tidak dapat memperoleh sumber yang diperlukan atas sebab tertentu dan tidak dapat meneruskan pelaksanaan. Untuk mengelakkan kebuluran, kita boleh menggunakan keutamaan kunci, penjadualan adil dan mekanisme lain untuk memastikan benang memperoleh sumber secara adil.

Berikut ialah contoh kod yang menggunakan keutamaan kunci mutex untuk menyelesaikan masalah kebuluran:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;
int counter = 0;

void increment() {
    std::unique_lock<std::mutex> lock(mtx, std::defer_lock);
    while (true) {
        lock.lock(); // 获取互斥锁
        counter++;
        lock.unlock(); // 释放互斥锁
    }
}

void decrement() {
    std::unique_lock<std::mutex> lock(mtx, std::defer_lock);
    while (true) {
        lock.lock(); // 获取互斥锁
        counter--;
        lock.unlock(); // 释放互斥锁
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(decrement);

    t1.join();
    t2.join();

    return 0;
}
Salin selepas log masuk

Dalam kod di atas, kami menggunakan parameter std::defer_lock untuk menangguhkan pemerolehan kunci mutex, dan kemudian panggil ia secara manual apabila diperlukan lock.lock() untuk mendapatkan kunci mutex. Ini memastikan bahawa benang memperoleh mutex secara adil dan mengelakkan masalah kebuluran.

Ringkasan:
Masalah penyegerakan berbilang benang merupakan salah satu cabaran penting dalam pengaturcaraan berbilang benang Pemilihan dan penggunaan mekanisme penyegerakan yang munasabah adalah kunci untuk menyelesaikan masalah ini. Dalam C++, kita boleh menggunakan kunci mutex, pembolehubah keadaan dan operasi atom untuk mencapai penyegerakan dan kerjasama antara benang. Dengan mereka bentuk dan menulis program berbilang benang dengan betul, kami boleh menyelesaikan masalah penyegerakan berbilang benang dengan berkesan dan meningkatkan prestasi dan kebolehpercayaan program.

Atas ialah kandungan terperinci Masalah penyegerakan berbilang benang dan penyelesaian dalam C++. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!