小编典典

互斥量示例/教程?

all

我是多线程的新手,并试图了解互斥锁是如何工作的。做了很多谷歌搜索,但它仍然对它的工作方式产生了一些疑问,因为我创建了自己的程序,其中锁定不起作用。

互斥锁的一种绝对不直观的语法是pthread_mutex_lock( &mutex1 );,看起来互斥锁被锁定了,而我真正想要锁定的是其他变量。这种语法是否意味着锁定互斥锁会锁定代码区域,直到互斥锁解锁?那么线程是如何知道该区域被锁定的呢?[
更新:线程知道该区域被
内存围栏锁定]。这种现象不应该被称为临界区吗?[
更新:关键部分对象仅在 Windows 中可用,其中对象比互斥锁更快,并且仅对实现它的线程可见。 否则,临界区只是指受互斥体保护的代码区域]

简而言之,您能否提供最简单的互斥锁 示例程序 以及关于其工作逻辑的最简单 解释? 我相信这会帮助 _ 很多_ 其他新手。


阅读 76

收藏
2022-07-02

共1个答案

小编典典

这是我向世界各地的新手解释这个概念的谦虚尝试:(
我的博客上也有一个颜色编码的版本)

很多人跑到一个单独的电话亭(他们没有手机)与亲人交谈。第一个抓住展位门把手的人,就是被允许使用电话的人。只要他使用电话,他就必须一直抓住门把手,否则别人会抓住把手,把他扔出去和他的妻子说话:)
没有这样的排队系统。当这个人打完电话,走出电话亭并离开门把手时,下一个抓住门把手的人将被允许使用电话。

线程* 是:每个人 互斥锁 :门把手 锁是:人
的手 资源 是 :电话
*



任何线程必须执行一些不应被其他线程同时修改的代码行(使用电话与他的妻子交谈),必须首先获得互斥锁上的锁(抓住展位的门把手)。只有这样,一个线程才能运行这些代码行(拨打电话)。

一旦线程执行了该代码,它应该释放互斥锁上的锁,以便另一个线程可以获得互斥锁上的锁(其他人能够访问电话亭)。

[ 在考虑现实世界的独占访问时,拥有互斥锁的概念有点荒谬,但在编程世界中,我想没有其他方法可以让其他线程“看到”一个线程已经在执行一些代码行。
有递归互斥锁等概念,但这个例子只是为了向你展示基本概念。希望这个例子能让你清楚地了解这个概念。
]

使用 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

2022-07-02