我很谦虚地向世界各地的新手解释这个概念:(我博客上的颜色编码版本也是如此)
很多人跑到一个孤独的电话亭(他们没有手机)与亲人聊天。第一个抓住展位门把手的人是被允许使用电话的人。只要使用电话,他就必须一直握住门的把手,否则其他人将抓住把手,将其扔出去并与妻子交谈:)没有这样的排队系统。当该人结束通话,走出展位并离开门把手时,将允许下一个握住门把手的人使用电话。
一个线程是:每个人
的互斥是:门把手
的锁是:人的手
的资源是:手机
任何必须执行一些代码行的线程(不应该同时被其他线程修改)(使用电话与妻子交谈),必须先获得一个互斥锁(抓住展位的门把手) )。只有这样,线程才能运行这些代码行(拨打电话)。
线程执行完该代码后,应释放互斥锁,以便另一个线程可以获取互斥锁(其他人可以访问电话亭)。
[ 当考虑现实世界中的互斥访问时,具有互斥体的概念有点荒谬,但是在编程世界中,我想没有其他方法可以让其他线程“看到”一个线程已经在执行某些代码行。这里有递归互斥的概念,但是这个例子只是为了向您展示基本概念。希望该示例可以使您对该概念有一个清晰的了解。]
使用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
相反的明确使用lock
和unlock
,你可以用括号如下图所示,如果您正在使用范围的锁,因为它提供了优势。但是,范围锁具有轻微的性能开销。