我是多线程的新手,我很难绕过互斥。
所以这是pthread_mutex_lock的原型
int pthread_mutex_lock(pthread_mutex_t *mutex);
手册页说The mutex object referenced by mutex shall be locked by calling pthread_mutex_lock().
首先,我的理解是你使用互斥锁来锁定共享资源,这样只有一个线程可以随时访问它。为了论证,让我们说共享资源是一个名为myVariable
的全局变量。现在,如果我们想要锁定myVariable,我应该可以使用锁定机制锁定myVariable
,但锁定mutex object
是什么意思?我的意思是,如果我拨打pthread_mutex_lock(&someMutex)
,我是否锁定myVariable
或其他内容?
如果我想使用互斥,我不应该做pthread_mutex_lock(myVariable)
而不是做pthread_mutex_lock(&someMutex)
这样的事情吗?
此someMutex
对象如何与myVariable对应?这个someMutex
对象如何锁定对myVariable
的访问权限?
P.S。假设我已经在自己之前声明了someMutex
。
P.P.S。我有一种感觉,这个问题可能很广泛,但话说再说一遍,我不应该问一些实际上有特定答案的事情(如果我错了,请纠正我)。
答案 0 :(得分:2)
互斥量与它保护的内容之间的关联不为互斥量所知,也不是必须的。假设我们有两个合作的人,他们需要共享汽车。当对方使用汽车时,我们不希望一个人尝试使用汽车。他们可以制定一个简单的规则 - 除非你拿着红萝卜,否则不要弄乱汽车。因为只有一个人可以拿着萝卜,这样可以确保他们在试图使用汽车时不会相互冲突。萝卜不必知道它"保护"车。只要他们都独自离开汽车,除非他们是拿着萝卜的人,萝卜会保护汽车。
互斥体是萝卜。锁定互斥锁持有萝卜,等待另一个人在需要时将其放下。解锁互斥锁将萝卜放在另一个人可以得到它的地方。
互斥锁保护的变量或对象是汽车。萝卜保护汽车不是来自萝卜所做的任何事情,而是来自遵守规则的每个人都不会触摸汽车,除非你有萝卜。同上互联网保护对象。
答案 1 :(得分:1)
someMutex
基本上只是一个数字变量,它不直接对应myVariable
一般顺序概念
lock(someMutex) {
while (someMutex != 0) {}
someMutex = 1;
}
unlock(someMutex) {
someMutex = 0;
}
答案 2 :(得分:0)
互斥锁保护代码区域,因此一次只执行一个执行线程。
互斥锁是一个基本构建块,您有责任应用它来获得所需的结果。
如果要更改共享变量,可以执行以下操作:
void changeit(int val)
{
pthread_mutex_lock(&someMutex);
global_variable = val;
pthread_mutex_unlock(&someMutex);
}
这部分意味着一次只有一个线程将在互斥锁的锁定/解锁之间执行代码。这是为了确保
global_variable = val;正在以原子方式运行,例如同时运行2个分配,不能保证结果是任何有意义的值 (不保证单个赋值语句以原子方式执行或作为汇编/机器代码中的1条指令执行)
任何阅读global_variable的人都会在有人更改之前或之后完全这样做,因此他们看不到任何在更改过程中的不一致值。
这也意味着访问(读取和/或写入)global_variable的任何其他人也必须在锁定相同的互斥锁时这样做,例如要读取变量,您可以这样做:
int readit(void)
{
int val;
pthread_mutex_lock(&someMutex);
val = global_variable;
pthread_mutex_unlock(&someMutex);
return val;
}
因此,someMutex
仅对代码的编写方式与global_variable
相对应,并且它依赖于您(程序员)正确执行 - {{1}之间没有内在联系}和global_variable
。
如果你的程序连接了两个变量并且必须始终一起读取或写入是有意义的,那么互斥锁允许你这样做 - 而不是像上面代码所示读取/写入单个变量,你可以读取/在保持互斥锁时更改2个变量。同样,互斥体对这两个变量一无所知,影响就是代码的结构。