网站开发 平台建设,互联网广告精准营销,建设网站的多少钱,网站排名优化各公司的2023年9月11日#xff0c;周一中午开始
2023年9月11日#xff0c;周一晚上23#xff1a;25写完 目录
概述头文件std::mutex类的成员类型方法没有std::mutex会产生什么问题问题一#xff1a;数据竞争问题二#xff1a;不一致lock和unlock死锁 概述
std::mutex是C标准库中…2023年9月11日周一中午开始
2023年9月11日周一晚上2325写完 目录
概述头文件std::mutex类的成员类型方法没有std::mutex会产生什么问题问题一数据竞争问题二不一致lock和unlock死锁 概述
std::mutex是C标准库中提供的一种同步原语用于保护共享资源的访问。
std::mutex通过锁定互斥锁来实现对共享资源的保护。当一个线程获取了互斥锁后其他线程必须等待该互斥锁被释放才能继续访问共享资源。这样可以确保在同一时刻只有一个线程能够访问共享资源从而避免了多个线程同时访问同一资源而导致的数据竞争和不一致问题。 头文件
#includemutex std::mutex类的成员
类型
native_handle_type 原生的互斥锁句柄类型
方法
(constructor) 构造互斥锁公共函数
lock 锁上互斥锁公共函数
try_lock 如果互斥锁没锁上就锁上互斥锁公共函数
unlock 解除互斥锁公共函数
native_handle 获取原生的互斥锁句柄公共函数 没有std::mutex会产生什么问题
问题一数据竞争
在这个程序中共享资源是countcount的值为0
按理来说一个线程给count增加100000另一个线程给count减去100000最后的count应该还是0但是事实上却不是这样这就是数据竞争所造成的。
#include iostream
#include mutex
#include threadint count 0;void thread1() {for(int i 0; i 100000; i) {count; }
}void thread2() {for(int i 0; i 100000; i) { count--;}
}int main() {std::thread t1(thread1);std::thread t2(thread2);t1.join();t2.join();std::cout count: count std::endl; // 可能打印非0值
}问题二不一致
多个线程对共享数据进行操作,由于缓存一致性问题,可能导致其中一个线程看到的数据不是最新值。
比如在这个程序里面有时候判断x1是true有时候判断x1是false
#include iostream
#include mutex
#include threadint x 0;void thread1() {x 1;
}void thread2() {if(x 1)std::cout x is 1 std::endl; elsestd::cout x is not 1 std::endl;
}int main() {std::thread t1(thread1);std::thread t2(thread2);t1.join();t2.join();}lock和unlock
通过lock/unlock可以保证任何时刻只有一个线程在访问共享资源,从而避免数据竞争问题。
#include iostream
#include mutex
#include threadstd::mutex mutex;
int count 0;void thread1() {for(int i 0; i 100000; i) {// 锁定互斥锁mutex.lock(); count; // 解锁互斥锁mutex.unlock();}
}void thread2() {for(int i 0; i 100000; i) { // 锁定互斥锁mutex.lock(); count--;// 解锁互斥锁mutex.unlock();}
}int main() {std::thread t1(thread1);std::thread t2(thread2);t1.join();t2.join();std::cout count: count std::endl;
}可以看到数据竞争的问题得到了解决 死锁
死锁Deadlock是多线程或多进程编程中的一个严重问题它会导致程序无法继续执行下去因为一组线程或进程相互等待对方释放资源但永远无法满足条件从而陷入僵局。
死锁的定义是多个线程因为抢占和持有资源而造成的一种互相等待的僵局状态。
#include iostream
#include thread
#include mutexstd::mutex mutex1;
std::mutex mutex2;void threadA() {std::cout Thread A: Attempting to lock mutex1... std::endl;mutex1.lock();std::this_thread::sleep_for(std::chrono::milliseconds(1));std::cout Thread A: Attempting to lock mutex2... std::endl;mutex2.lock();// 执行任务...mutex2.unlock();mutex1.unlock();
}void threadB() {std::cout Thread B: Attempting to lock mutex2... std::endl;mutex2.lock();std::this_thread::sleep_for(std::chrono::milliseconds(1));std::cout Thread B: Attempting to lock mutex1... std::endl;mutex1.lock();// 执行任务...mutex1.unlock();mutex2.unlock();
}int main() {std::thread t1(threadA);std::thread t2(threadB);t1.join();t2.join();return 0;
}可以看到程序一直卡住
为什么会卡住呢 线程A首先尝试锁定mutex1并成功获得锁。 线程B首先尝试锁定mutex2并成功获得锁。 接下来线程A想要锁定mutex2但它被线程B持有因此线程A被阻塞无法继续执行等待mutex2被释放。 同样地线程B想要锁定mutex1但它被线程A持有因此线程B也被阻塞等待mutex1被释放。
现在线程A和线程B都被阻塞它们相互等待对方释放资源但又不会主动释放自己的锁。这就是典型的死锁情况两个或多个线程互相等待对方释放资源导致程序无法继续执行下去。
根本原因在于线程拿不到锁时就会被阻塞。