欢迎关注本公众号,专注面试题拆解
分享一套视频课程:《C++实现百万并发服务器》 面试需要项目的可以找我获取 ,免费分享。 欢迎V:fb964919126
多线程编程中互斥与同步有什么区别?两者之间是什么关系?
很多时候说互斥和同步都是一起说的,那么这两者之间是个什么关系呢?先给出我的结论:互斥是一种特殊的同步,同步都是互斥的。其实我感觉可以去掉这个互斥的概念,只说同步,同步就包含了互斥。
01
互斥(Mutex)
互斥主要用于保护对共享资源的访问,确保在同一时刻只有一个线程可以访问共享资源。互斥可以防止多个线程同时修改同一个数据,从而避免数据竞争条件(race conditions)。
最常用的互斥机制是互斥锁。
互斥锁通常用来保护临界区(critical section),即一段不能被多个线程同时访问的代码或数据。通过互斥锁,可以确保在某一时刻只有一个线程可以进入临界区,具有排它性。但互斥锁无法限制访问者对资源的访问顺序,即访问是无序的。
举个例子:
厕所只有一个位置,现在有3个人要上厕所,互斥只能达到控制一个时间只能一个人上的效果,但是这个3个人谁先上是不管的。
代码示例:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int shared_data = 0;
void incrementSharedData() {
std::lock_guard<std::mutex> lock(mtx);
shared_data++;
std::cout << "Thread " << std::this_thread::get_id() << " incremented shared_data to " << shared_data << std::endl;
}
int main() {
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i) {
threads.emplace_back(incrementSharedData);
}
for (auto& t : threads) {
t.join();
}
std::cout << "Final value of shared_data: " << shared_data << std::endl;
return 0;
}
互斥解决了多线程对临界区使用的问题,但是它没有解决多进程协同工作的问题。
02
同步
同步(Synchronization)指的是在多线程环境中协调不同线程之间的执行顺序,以确保它们按照预期的方式执行。同步机制不仅可以解决互斥问题,还可以解决线程之间的协作问题。
同步在互斥的基础上,通过其它机制实现访问者对资源的有序访问,它解决的是一个时间顺序问题。所以说同步已经实现了互斥。
举个例子:
银行办事大厅的一个窗口,有10个人取号,按照号码顺序来进行办理业务。
同步的特点:
协调执行:确保线程按照一定的顺序执行。
多种机制:除了互斥锁之外,还包括信号量(Semaphore)、条件变量、原子操作、屏障等。
示例代码:互斥锁+条件变量实现同步
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void waitForReady() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return ready; });
std::cout << "Thread " << std::this_thread::get_id() << " detected that ready is true" << std::endl;
}
void setReady() {
{
std::lock_guard<std::mutex> lock(mtx);
ready = true;
}
cv.notify_one();
}
int main() {
std::thread waiting_thread(waitForReady);
std::this_thread::sleep_for(std::chrono::seconds(1));
std::thread setting_thread(setReady);
waiting_thread.join();
setting_thread.join();
return 0;
}
同步就是多线程间在一些关键点上可能需要互相等待与互通消息,比如一个线程达到某个条件另外一个线程才可以执行,这种相互制约的等待与互通信息称为线程同步。
03
区别
目的不同:
互斥:主要用于保护对共享资源的访问,防止数据竞争条件。
同步:不仅用于解决互斥问题,还用于协调线程间的执行顺序,实现更复杂的同步逻辑。
机制不同:
互斥:通常使用互斥锁(Mutex)来实现。
同步:可以使用互斥锁、信号量、条件变量等多种机制来实现。
适用场景不同:
互斥:适用于保护对共享资源的访问。
同步:适用于协调线程间的执行顺序,实现线程间的协作。
总结:
互斥是一种特殊的同步,同步是一种更为复杂的互斥。
互斥是两个线程之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,另一个才能运行。
同步是不能同时运行,但必须要按照某种次序来运行相应的线程(也是一种互斥)
end
CppPlayer
关注,回复【电子书】珍藏CPP电子书资料赠送
精彩文章合集
专题推荐