溫馨提示×

Linux C++中如何進行并發控制

小樊
45
2025-08-20 04:32:40
欄目: 編程語言

在Linux環境下使用C++進行并發控制,可以采用多種機制來確保線程安全和管理多個線程之間的交互。以下是幾種常用的方法和示例:

1. 使用互斥鎖(Mutex)

互斥鎖用于保護共享資源,防止多個線程同時訪問導致的數據競爭。

示例代碼:

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

std::mutex mtx; // 全局互斥鎖
int shared_variable = 0;

void increment() {
    mtx.lock(); // 加鎖
    ++shared_variable;
    mtx.unlock(); // 解鎖
}

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

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

    std::cout << "Shared Variable: " << shared_variable << std::endl;
    return 0;
}

使用std::lock_guard簡化鎖管理:

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

std::mutex mtx;
int shared_variable = 0;

void increment() {
    std::lock_guard<std::mutex> lock(mtx); // RAII方式自動管理鎖
    ++shared_variable;
}

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

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

    std::cout << "Shared Variable: " << shared_variable << std::endl;
    return 0;
}

2. 使用條件變量(Condition Variables)

條件變量用于線程間的同步,允許一個線程等待某個條件成立,而另一個線程在條件滿足時通知等待的線程。

示例代碼:

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

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void worker() {
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, []{ return ready; }); // 等待條件變量
    std::cout << "Worker thread is processing data.\n";
}

void trigger() {
    std::this_thread::sleep_for(std::chrono::seconds(1)); // 模擬一些工作
    {
        std::lock_guard<std::mutex> lock(mtx);
        ready = true;
    }
    cv.notify_one(); // 通知等待的線程
}

int main() {
    std::thread t1(worker);
    std::thread t2(trigger);

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

    return 0;
}

3. 使用原子操作(Atomic Operations)

C++11引入了<atomic>庫,提供了原子類型,可以在不使用鎖的情況下實現線程安全的操作。

示例代碼:

#include <iostream>
#include <thread>
#include <atomic>

std::atomic<int> shared_variable(0);

void increment() {
    ++shared_variable; // 原子操作,無需鎖
}

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

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

    std::cout << "Shared Variable: " << shared_variable << std::endl;
    return 0;
}

4. 使用信號量(Semaphores)

雖然C++標準庫沒有直接支持信號量,但可以使用POSIX信號量或第三方庫(如Boost)來實現。

使用POSIX信號量的示例:

#include <iostream>
#include <thread>
#include <semaphore.h>

sem_t sem;

void worker() {
    sem_wait(&sem); // 等待信號量
    std::cout << "Worker thread is processing data.\n";
    sem_post(&sem); // 釋放信號量
}

int main() {
    sem_init(&sem, 0, 1); // 初始化信號量,初始值為1

    std::thread t1(worker);
    std::thread t2(worker);

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

    sem_destroy(&sem);
    return 0;
}

5. 使用讀寫鎖(Reader-Writer Locks)

當共享資源讀取操作遠多于寫入操作時,使用讀寫鎖可以提高并發性能。C++17引入了std::shared_mutex。

示例代碼:

#include <iostream>
#include <thread>
#include <shared_mutex>

std::shared_mutex rw_mtx;
int shared_data = 0;

// 讀取函數
void read_data() {
    std::shared_lock<std::shared_mutex> lock(rw_mtx); // 共享鎖
    std::cout << "Read data: " << shared_data << std::endl;
}

// 寫入函數
void write_data(int value) {
    std::unique_lock<std::shared_mutex> lock(rw_mtx); // 獨占鎖
    shared_data = value;
    std::cout << "Write data: " << shared_data << std::endl;
}

int main() {
    std::thread t1(read_data);
    std::thread t2(write_data, 42);
    std::thread t3(read_data);

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

    return 0;
}

6. 使用線程池和任務隊列

為了更高效地管理線程和處理任務,可以使用線程池和任務隊列。這可以減少線程創建和銷毀的開銷,并簡化并發控制。

示例代碼(使用C++11的std::queuestd::mutex實現簡單的生產者-消費者模型):

#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>

class ThreadPool {
public:
    ThreadPool(size_t threads) : stop(false) {
        for(size_t i = 0; i < threads; ++i)
            workers.emplace_back([this](){
                while(true){
                    std::function<void()> task;
                    {
                        std::unique_lock<std::mutex> lock(this->queue_mutex);
                        this->condition.wait(lock, [this]{ return this->stop || !this->tasks.empty(); });
                        if(this->stop && this->tasks.empty())
                            return;
                        task = std::move(this->tasks.front());
                        this->tasks.pop();
                    }
                    task();
                }
            });
    }

    template<class F, class... Args>
    void enqueue(F&& f, Args&&... args) {
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            tasks.emplace([f, args...](){ f(args...); });
        }
        condition.notify_one();
    }

    ~ThreadPool(){
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            stop = true;
        }
        condition.notify_all();
        for(std::thread &worker: workers)
            worker.join();
    }

private:
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> tasks;
    std::mutex queue_mutex;
    std::condition_variable condition;
    bool stop;
};

int main(){
    ThreadPool pool(4);
    int task_num = 8;

    for(int i = 0; i < task_num; ++i){
        pool.enqueue([i](){
            std::cout << "Task "<< i << " is running in thread " << std::this_thread::get_id() << "\n";
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
            std::cout << "Task "<< i << " completed.\n";
        });
    }

    // 主線程可以繼續執行其他任務或等待
    return 0;
}

總結

在Linux環境下使用C++進行并發控制時,可以根據具體需求選擇合適的同步機制:

  • 互斥鎖適用于保護共享資源,防止數據競爭。
  • 條件變量用于線程間的協調和通信。
  • 原子操作適用于簡單的共享變量操作,無需鎖。
  • 信號量適用于更復雜的同步需求。
  • 讀寫鎖適用于讀多寫少的場景,提高并發性能。
  • 線程池用于高效地管理線程和處理任務。

合理使用這些工具和方法,可以有效地實現線程安全和高效的并發控制。

0
亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女