我是多线程的新手,并试图了解互斥锁是如何工作的。做了很多谷歌搜索,但它仍然对它的工作方式产生了一些疑问,因为我创建了自己的程序,其中锁定不起作用。
互斥锁的一种绝对不直观的语法是pthread_mutex_lock( &mutex1 );,看起来互斥锁被锁定了,而我真正想要锁定的是其他变量。这种语法是否意味着锁定互斥锁会锁定代码区域,直到互斥锁解锁?那么线程是如何知道该区域被锁定的呢?[ 更新:线程知道该区域被 内存围栏锁定]。这种现象不应该被称为临界区吗?[ 更新:关键部分对象仅在 Windows 中可用,其中对象比互斥锁更快,并且仅对实现它的线程可见。 否则,临界区只是指受互斥体保护的代码区域]
pthread_mutex_lock( &mutex1 );
简而言之,您能否提供最简单的互斥锁 示例程序 以及关于其工作逻辑的最简单 解释? 我相信这会帮助 _ 很多_ 其他新手。
这是我向世界各地的新手解释这个概念的谦虚尝试:( 我的博客上也有一个颜色编码的版本)
很多人跑到一个单独的电话亭(他们没有手机)与亲人交谈。第一个抓住展位门把手的人,就是被允许使用电话的人。只要他使用电话,他就必须一直抓住门把手,否则别人会抓住把手,把他扔出去和他的妻子说话:) 没有这样的排队系统。当这个人打完电话,走出电话亭并离开门把手时,下一个抓住门把手的人将被允许使用电话。
线程* 是:每个人 互斥锁 是 :门把手 锁是:人 的手 资源 是 :电话 *
任何线程必须执行一些不应被其他线程同时修改的代码行(使用电话与他的妻子交谈),必须首先获得互斥锁上的锁(抓住展位的门把手)。只有这样,一个线程才能运行这些代码行(拨打电话)。
一旦线程执行了该代码,它应该释放互斥锁上的锁,以便另一个线程可以获得互斥锁上的锁(其他人能够访问电话亭)。
[ 在考虑现实世界的独占访问时,拥有互斥锁的概念有点荒谬,但在编程世界中,我想没有其他方法可以让其他线程“看到”一个线程已经在执行一些代码行。 有递归互斥锁等概念,但这个例子只是为了向你展示基本概念。希望这个例子能让你清楚地了解这个概念。]
使用 C++11 线程:
#include <iostream> #include <thread> #include <mutex> std::mutex m;//you can use std::lock_guard if you want to be exception safe int i = 0; void makeACallFromPhoneBooth() { m.lock();//man gets a hold of the phone booth door and locks it. The other men wait outside //man happily talks to his wife from now.... std::cout << i << " Hello Wife" << std::endl; i++;//no other thread can access variable i until m.unlock() is called //...until now, with no interruption from other men m.unlock();//man lets go of the door handle and unlocks the door } int main() { //This is the main crowd of people uninterested in making a phone call //man1 leaves the crowd to go to the phone booth std::thread man1(makeACallFromPhoneBooth); //Although man2 appears to start second, there's a good chance he might //reach the phone booth before man1 std::thread man2(makeACallFromPhoneBooth); //And hey, man3 also joined the race to the booth std::thread man3(makeACallFromPhoneBooth); man1.join();//man1 finished his phone call and joins the crowd man2.join();//man2 finished his phone call and joins the crowd man3.join();//man3 finished his phone call and joins the crowd return 0; }
编译并运行使用g++ -std=c++0x -pthread -o thread thread.cpp;./thread
g++ -std=c++0x -pthread -o thread thread.cpp;./thread