C 线程在同一互斥锁的多个锁上的行为

C 线程在同一互斥锁的多个锁上的行为,c,pthreads,mutex,C,Pthreads,Mutex,如果我在函数中的两个不同位置锁定同一个互斥锁,并且当一个线程在其中一个线程中时发生上下文切换,而第二个线程到达另一个线程时,它会被阻塞吗 我将试着给出一个简单的例子来说明我的意思,也许会更清楚。 假设我在test.c文件中有以下代码 int globalVar = 0; void testMutex(pthread_mutex_t myMutex) { pthread_mutex_lock(&myMutex); globalVar++; pthread_

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

我将试着给出一个简单的例子来说明我的意思,也许会更清楚。 假设我在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中,我有一个main函数,它创建两个线程,
thread1
thread2
,都运行
testMutex
函数。
thread1
首先执行,而在函数的第二部分(在
printf
之后的--part)中,在互斥锁解锁之前,
thread2
从函数开始开始运行。
thread2
是否能够执行
globalVar++
,或者它会一直被阻止,等待互斥锁解锁

提前谢谢

简短的回答是“是”

这一点非常清楚:

应通过调用pthread_mutex_lock()锁定互斥体引用的互斥体对象。如果互斥锁已经锁定,调用线程将阻塞,直到互斥锁可用。此操作将返回,互斥体引用的互斥体对象处于锁定状态,调用线程作为其所有者

换句话说,从
pthread\u mutex\u lock
返回时,互斥锁由线程“拥有”。系统保证在任何时候最多有一个线程可以“拥有”一个互斥锁。

简短的回答是“是”

这一点非常清楚:

应通过调用pthread_mutex_lock()锁定互斥体引用的互斥体对象。如果互斥锁已经锁定,调用线程将阻塞,直到互斥锁可用。此操作将返回,互斥体引用的互斥体对象处于锁定状态,调用线程作为其所有者


换句话说,从
pthread\u mutex\u lock
返回时,互斥锁由线程“拥有”。系统保证在任何时候最多有一个线程可以“拥有”一个互斥体。

首先,您不应该通过值传递
pthread\u mutex\t

void testMutex(pthread_mutex_t myMutex)
使其成为
pthread\u mutex\u t*
。尽管您的代码可能适合您(我对此表示怀疑),但它是不可移植的,因为
pthreads
类型是不透明的

。除此之外,它还暗示了一种可能性,即使用
pthread\u mutex\u t
会导致每次调用
testMutex
时都生成互斥体的副本(使用函数锁定副本而不是原始互斥体)

修复此问题后,以下内容将保持不变:

由于两个线程使用相同的互斥锁,因此只要第一个线程位于两个
pthread\u mutex\u lock
节中的任何一个节内,则在两个
pthread\u mutex\u lock
节上具有块的第二个线程就会调用。反之亦然(只要第二个线程有互斥锁,第一个线程就会阻塞)


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

首先,您不应该通过值传递
pthread\u mutex\t

void testMutex(pthread_mutex_t myMutex)
使其成为
pthread\u mutex\u t*
。尽管您的代码可能适合您(我对此表示怀疑),但它是不可移植的,因为
pthreads
类型是不透明的

。除此之外,它还暗示了一种可能性,即使用
pthread\u mutex\u t
会导致每次调用
testMutex
时都生成互斥体的副本(使用函数锁定副本而不是原始互斥体)

修复此问题后,以下内容将保持不变:

由于两个线程使用相同的互斥锁,因此只要第一个线程位于两个
pthread\u mutex\u lock
节中的任何一个节内,则在两个
pthread\u mutex\u lock
节上具有块的第二个线程就会调用。反之亦然(只要第二个线程有互斥锁,第一个线程就会阻塞)


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

thread2将在pthread\u mutex\u lock()函数中阻塞,直到thread1解锁互斥锁


如果不是,互斥锁的第一个用途是什么?

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


如果没有,,互斥锁的第一个用途是什么?

thread2将保持被阻止状态,并且在thread1释放互斥锁之前无法增加GlobalArr++。

thread2将保持被阻止状态,并且在thread1释放互斥锁之前无法增加GlobalArr++。

函数中的位置并不重要-如果有一个线程释放互斥锁如果一个线程有互斥锁,另一个就不能得到它。

函数中的位置并不重要-如果一个线程有互斥锁,那么另一个线程就不能得到它。

我认为没有任何实现可以使用此代码。相反,
pthread\u mutex\u lock
将锁定互斥锁的副本,这不会阻止其他线程。从技术上讲,在互斥体的副本上执行任何操作都会导致UB,但这种行为几乎可以肯定,正如我刚才为实际实现所描述的那样。实际上,您链接的常见问题解答中的文本是错误的。与它所说的相反,复制
pthread\u t
是完全有效的,事实上,标准函数中
pthread\u t
的所有使用都是通过值(即使它是一个结构)而不是通过引用传递它,除了
pthread\u create
传递存储结果的地址之外。当然,
pthread\u t
本身通常是一个指向不透明数据结构的指针……我认为没有任何实现可以使用此代码。相反,
pthread\u mutex\u lock
将锁定