C++ 并发专题 - C++线程同步的几种方法
一:概述
线程同步是多线程编程中的一个重要概念,它用于控制多个线程之间对共享资源的访问,避免竞态条件(race condition)和数据不一致的问题。线程同步确保在多线程环境中,多个线程访问共享数据时能够按照某种预定的顺序或规则进行,以保证程序的正确性和稳定性。
二:线程同步方法
1. 信号量
#include <iostream>
#include <semaphore>
#include <thread>
#include <vector>
std::vector<int> myVec{};
std::counting_semaphore<1> prepareSignal(0);
void prepareWork() {
myVec.insert(myVec.end(), {0, 1, 0, 3});
std::cout << "Sender: Data prepared." << '\n';
prepareSignal.release();
}
void completeWork() {
std::cout << "Waiter: Waiting for data." << '\n';
prepareSignal.acquire();
myVec[2] = 2;
std::cout << "Waiter: Complete the work." << '\n';
for (auto i: myVec) std::cout << i << " ";
std::cout << '\n';
}
int main() {
std::cout << '\n';
std::thread t1(prepareWork);
std::thread t2(completeWork);
t1.join();
t2.join();
std::cout << '\n';
}
2. 条件变量
#include <iostream>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <vector>
std::mutex mut;
std::condition_variable condVar;
std::vector<int> myVec{};
void prepareWork() {
{
std::lock_guard<std::mutex> lck(mut);
myVec.insert(myVec.end(), {0, 1, 0, 3});
}
std::cout << "Sender: Data prepared." << '\n';
condVar.notify_one();
}
void completeWork() {
std::cout << "Waiter: Waiting for data." << '\n';
std::unique_lock<std::mutex> lck(mut);
condVar.wait(lck, [] { return not myVec.empty(); });
myVec[2] = 2;
std::cout << "Waiter: Complete the work." << '\n';
for (auto i: myVec) std::cout << i << " ";
std::cout << '\n';
}
int main() {
std::cout << '\n';
std::thread t1(prepareWork);
std::thread t2(completeWork);
t1.join();
t2.join();
std::cout << '\n';
}
3. Atomic
#include <atomic>
#include <iostream>
#include <thread>
#include <vector>
std::vector<int> myVec{};
std::atomic<bool> atomicBool{false};
void prepareWork() {
myVec.insert(myVec.end(), {0, 1, 0, 3});
std::cout << "Sender: Data prepared." << '\n';
atomicBool.store(true);
atomicBool.notify_one();
}
void completeWork() {
std::cout << "Waiter: Waiting for data." << '\n';
atomicBool.wait(false);
myVec[2] = 2;
std::cout << "Waiter: Complete the work." << '\n';
for (auto i: myVec) std::cout << i << " ";
std::cout << '\n';
}
int main() {
std::cout << '\n';
std::thread t1(prepareWork);
std::thread t2(completeWork);
t1.join();
t2.join();
std::cout << '\n';
}
4. Promise - Feature
#include <iostream>
#include <future>
#include <thread>
#include <vector>
std::vector<int> myVec{};
void prepareWork(std::promise<void> prom) {
myVec.insert(myVec.end(), {0, 1, 0, 3});
std::cout << "Sender: Data prepared." << '\n';
prom.set_value();
}
void completeWork(std::future<void> fut){
std::cout << "Waiter: Waiting for data." << '\n';
fut.wait();
myVec[2] = 2;
std::cout << "Waiter: Complete the work." << '\n';
for (auto i: myVec) std::cout << i << " ";
std::cout << '\n';
}
int main() {
std::cout << '\n';
std::promise<void> sendNotification;
auto waitForNotification = sendNotification.get_future();
std::thread t1(prepareWork, std::move(sendNotification));
std::thread t2(completeWork, std::move(waitForNotification));
t1.join();
t2.join();
std::cout << '\n';
}