问题描述
我是新的多线程,并试图了解互斥的工作。做了很多的谷歌搜索和我找到一份像样的教程,但仍留下了它是如何工作的,因为我有些疑惑创建了自己的方案,其中锁定没有工作。
I'm new to multithreading, and was trying to understand how mutexes work. Did a lot of Googling and I found a decent tutorial, but it still left some doubts of how it works because I created my own program in which locking didn't work.
互斥的一个绝对的非直观的语法是的pthread_mutex_lock(安培;互斥锁);
,它看起来像互斥被锁定,当我真的想锁是一些其他的变量。这是否语法意味着锁定一个互斥锁code的区域,直到互斥量被释放?那怎么办线程知道该区域被锁定? [更新:线程知道该区域已被锁定,由的Memory击剑。而不是这样的设想被称作临界区的现象呢? [更新:临界区对象仅适用于Windows,那里的对象是不是互斥更快,可见只有它实现它的线程可用。否则,临界区仅仅是指code与互斥保护的区域的]
One absolutely non-intuitive syntax of the mutex is pthread_mutex_lock( &mutex1 );
, where it looks like the mutex is being locked, when what I really want to lock is some other variable. Does this syntax mean that locking a mutex locks a region of code until the mutex is unlocked? Then how do threads know that the region is locked? [UPDATE: Threads know that the region is locked, by Memory Fencing ]. And isn't such a phenomenon supposed to be called critical section? [UPDATE: Critical section objects are available in Windows only, where the objects are faster than mutexes and are visible only to the thread which implements it. Otherwise, critical section just refers to the area of code protected by a mutex]
总之,请你用最简单的可能互斥帮助示例程序并尽可能简单的说明在它是如何工作的逻辑是什么?我敢肯定,这将有助于 大量的其他新手的。
In short, could you please help with the simplest possible mutex example program and the simplest possible explanation on the logic of how it works? I'm sure this will help plenty of other newbies.
推荐答案
的编辑的解释和code是最欢迎(以使其更清晰/短/简单/更正确的)。结果
在这里不用我卑微试图解释这个概念给世界各地的新手:(一太)的
很多人跑到一个孤独的电话亭(无手机)谈谈自己的亲人。搭上展位的门把手的第一个人,是谁被允许使用手机的人。他必须坚持下去,以他只要使用手机门的把手,否则别人会抓住手柄的举行,把他丢出去,跟他的妻子:)有没有排队系统本身。当人完成他的电话,出来的展位和叶门把手,旁边的人得到门把手保持一律不准使用手机。
A lot of people run to a lone phone booth (no mobiles) to talk to their loved ones. The first person to catch the door-handle of the booth, is the one who is allowed to use the phone. He has to keep holding on to the handle of the door as long as he uses the phone, otherwise someone else will catch hold of the handle, throw him out and talk to his wife :) There's no queue system as such. When the person finishes his call, comes out of the booth and leaves the door handle, the next person to get hold of the door handle will be allowed to use the phone.
A 线程是:每个人结果
在互斥为:门把手结果
在锁定为:人的手结果
在资源是:手机
A thread is : Each person
The mutex is : The door handle
The lock is : The person's hand
The resource is : The phone
有执行code,不应被其他线程在同一时间被修改的部分线路任何线程(使用电话向他的妻子),必须首先获得一个互斥锁(抓着展位的门把手)。只有这样,一个线程能够运行code的那些行(使得手机通话)。
Any thread which has to execute some lines of code which should not be modified by other threads at the same time (using the phone to talk to his wife), has to first acquire a lock on a mutex (clutching the door handle of the booth). Only then will a thread be able to run those lines of code (making the phone call).
在该线程已执行的code,应该释放锁的互斥以便另一个线程可以获取关于该互斥锁定(其他人能够访问电话亭)
Once the thread has executed that code, it should release the lock on the mutex so that another thread can acquire a lock on the mutex (other people being able to access the phone booth).
[有一个互斥体的概念是考虑到现实世界的独家访问时,有点荒唐,但在编程世界里,我想有没有别的办法,让其他线程'看',一个线程已经执行code的一些行。有递归互斥体等概念,但是这个例子只是为了你展示的基本概念。希望这个例子给你一个概念清晰的画面。的]
用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.cpp运行; ./线程
随着TBB:
你需要运行下面的程序,但发布TBB code的意图是让你明白的序列锁定和只是(可能已经展示范围不使用获取和释放锁定看着简单code解锁 - 的 - ,但这是更清晰)
With TBB:You'll need TBB to run the below program, but the intent of posting TBB code is that you understand the sequence of locking and unlocking just by looking at the simple code (could've shown scoped locking by not using acquire and release - which also is exception safe -, but this is clearer).
#include <iostream>
#include "/tbb/mutex.h"
#include "/tbb/tbb_thread.h"
using namespace tbb;
typedef mutex myMutex;
static myMutex sm;
int i = 0;
void someFunction()
{
//Note: Since a scoped lock is used below, you should know that you
//can specify a scope for the mutex using curly brackets, instead of
//using lock.acquire() and lock.release(). The lock will automatically
//get released when program control goes beyond the scope.
myMutex::scoped_lock lock;//create a lock
lock.acquire(sm);//Method acquire waits until it can acquire a lock on the mutex
//***only one thread can access the lines from here...***
++i;//incrementing i is safe (only one thread can execute the code in this scope) because the mutex locked above protects all lines of code until the lock release.
sleep(1);//simply creating a delay to show that no other thread can increment i until release() is executed
std::cout<<"In someFunction "<<i<<"\n";
//***...to here***
lock.release();//releases the lock (duh!)
}
int main()
{
tbb_thread my_thread1(someFunction);//create a thread which executes 'someFunction'
tbb_thread my_thread2(someFunction);
tbb_thread my_thread3(someFunction);
my_thread1.join();//This command causes the main thread (which is the 'calling-thread' in this case) to wait until thread1 completes its task.
my_thread2.join();
my_thread3.join();
}
注意 tbb_thread.h
是pcated德$ P $。更换显示here.
此外,而不是明确使用锁定
和解锁
,您可以用括号的中的优势。
Note that tbb_thread.h
is deprecated. The replacement is shown here.
Also, instead of explicitly using lock
and unlock
, you can use brackets as shown here, if you are using a scoped lock for the advantage it provides.
这篇关于例如互斥/教程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!