C++ 标准库中的线程同步库提供了一组原语,用于在多线程环境中实现数据共享和保护
std::mutex
是 C++ 中最基本的同步原语之一。它提供了一种方法来保护共享数据,以防止多个线程同时访问。当一个线程锁定互斥锁时,其他试图锁定该互斥锁的线程将被阻塞,直到锁被解锁。
示例:
#include<iostream>
#include<thread>
#include <mutex>
std::mutex mtx; // 全局互斥锁
int shared_data = 0; // 共享数据
void thread_function() {
std::unique_lock<std::mutex> lock(mtx); // 锁定互斥锁
++shared_data; // 修改共享数据
lock.unlock(); // 解锁互斥锁
}
int main() {
std::thread t1(thread_function);
std::thread t2(thread_function);
t1.join();
t2.join();
std::cout << "Shared data: "<< shared_data<< std::endl;
return 0;
}
std::recursive_mutex
类似于 std::mutex
,但允许同一线程多次锁定相同的互斥锁。这在某些情况下可能很有用,例如在递归函数中保护共享数据。
std::chrono
是 C++ 中处理时间的库,它提供了高精度时间测量和时间点操作。这对于实现超时锁定和定时任务非常有用。
std::condition_variable
是一个同步原语,允许一个或多个线程等待某个条件成立。当条件成立时,线程将被唤醒并继续执行。条件变量通常与互斥锁一起使用,以确保线程安全地访问共享数据。
示例:
#include<iostream>
#include<thread>
#include <mutex>
#include<condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false; // 共享数据
void print_id() {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) { // 如果 ready 为 false,则等待
cv.wait(lck); // 当前线程被阻塞,并释放锁
}
std::cout << "Thread "<< std::this_thread::get_id() << " is ready\n";
}
void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true; // 修改共享数据
cv.notify_all(); // 唤醒所有等待的线程
}
int main() {
std::thread threads[10];
for (auto &th : threads) {
th = std::thread(print_id);
}
std::this_thread::sleep_for(std::chrono::seconds(1));
go(); // 修改 ready 并唤醒所有线程
for (auto &th : threads) {
th.join();
}
return 0;
}
std::shared_mutex
是一种特殊类型的互斥锁,允许多个线程同时读取共享数据,但只允许一个线程写入。这在读操作远多于写操作的场景中非常有用,因为它可以提高性能。
std::atomic
是一种特殊类型的变量,支持无锁编程。原子操作是不可分割的,这意味着它们在多线程环境中是线程安全的。原子操作通常比使用互斥锁更高效,但它们的功能有限,只支持基本的算术和逻辑操作。
C++11 引入了 thread_local
关键字,用于声明线程局部变量。线程局部变量在每个线程中都有自己的实例,因此它们不需要同步。这可以用于存储每个线程的状态信息或缓存数据。
总之,C++ 标准库提供了一组强大的同步原语,可以帮助开发人员在多线程环境中实现高效、安全的数据共享和保护。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。