2011-06-06 124 views
0

如果我在函数中的两个不同位置锁定相同的互斥锁,并且当一个线程位于其中一个线程中并且第二个线程到达另一个线程时发生上下文切换,它会被封锁吗?线程在同一互斥锁的多个锁上的行为

我会试着给出一个简单的例子,我的意思是,也许它会更清晰。 说我有下面的代码在一个文件test.c的

int globalVar = 0;  

void testMutex(pthread_mutex_t myMutex) { 
    pthread_mutex_lock(&myMutex); 
    globalVar++; 
    pthread_mutex_unlock(&myMutex); 

    printf("%s \n", "Doing some other stuff here"); 

    pthread_mutex_lock(&myMutex); 
    globalVar--; 
    pthread_mutex_unlock(&myMutex); 
} 

,并在不同的文件main.c中,我有创建两个线程,thread1thread2,都运行testMutex功能的主要功能。 thread1首先被执行,而在函数的第二部分( - 部分,在printf之后),在mutex被解锁之前,thread2从函数开始运行。 将thread2能够执行globalVar++,还是会保持阻止状态,等待互斥锁被解锁?

在此先感谢!

回答

3

简短回答是“是”。

pthread_mutex_lock documentation使这很清楚:

mutex引用的互斥对象应的pthread_mutex_lock调用被锁定()。如果互斥锁已被锁定,则调用线程应阻塞,直到互斥锁变为可用。该操作将返回互斥体对象,该互斥体对象在调用线程作为其所有者的锁定状态下由互斥量引用。

换句话说,从pthread_mutex_lock返回时,互斥量由线程“拥有”。系统保证最多一个线程可以随时“拥有”一个互斥体。

4

首先,你不应该四处传递pthread_mutex_t按值:

void testMutex(pthread_mutex_t myMutex) 

作出这样的pthread_mutex_t*。即使您的代码可能为您工作(我怀疑),它不是可移植的,因为pthreads类型意味着不透明。

There's a discussion of this in the relevant FAQ。除此之外,它暗示了您使用pthread_mutex_t会导致每次调用testMutex时互斥体的副本(使用锁定副本而不是原始互斥锁的功能)的副本。

一旦你解决了这个,下面将举行:

由于两个线程都使用相同的互斥体,以块第二个线程在任意一个pthread_mutex_lock电话,只要第一个线程在两个pthread_mutex_lock - pthread_mutex_unlock部分的内部。反过来也是如此(只要第二个线程具有互斥体,第一个线程就会阻塞)。

换句话说,只要一个线程对互斥量具有锁定,其他线程就不能锁定相同的互斥量。

+0

我不认为有这个代码将工作的任何实现。相反,'pthread_mutex_lock'会锁定一个*互斥锁的副本,它不会阻塞其他线程。技术上对互斥副本执行任何操作都会导致UB,但行为几乎可以肯定地像我刚才描述的那样用于实际实现。 – 2011-06-06 19:08:53

+1

其实您链接的FAQ中的文本是错误的。与它所说的相反,复制'pthread_t'完全有效,事实上,在标准函数中'pthread_t'的所有用法都是通过值(即使它是一个结构)而不是通过引用来传递它,除了'pthread_create',其中地址来存储结果通过。当然,'pthread_t'通常本身就是一个指向不透明数据结构的指针。 – 2011-10-15 04:47:08

1

thread2将阻塞在pthread_mutex_lock()函数中,直到thread1解锁互斥锁为止。

如果没有,那么互斥体的目的是什么呢?

0

线程2将保持阻塞状态,直到线程1释放互斥锁后才能增加globalVarr ++。

0

函数中的位置并不重要 - 如果一个线程有互斥锁,另一个线程不能获取它。