面试题:多线程编程中互斥与同步有什么区别?两者之间是什么关系?

旅行   2024-10-21 11:54   广东  

欢迎关注本公众号,专注面试题拆解

分享一套视频课程:《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电子书资料赠送

精彩文章合集

专题推荐

【专辑】计算机网络真题拆解
【专辑】大厂最新真题
【专辑】C/C++面试真题拆解

CppPlayer
一个专注面试题拆解的公众号
 最新文章