我是初学者,所以如果问题不明确,请告诉我。
我使用两个线程,例如A和B.我有一个全局变量'p'。 线程A在循环并递增'p'的值时。同时B试图用其他值设置'p'(两个都是两个不同的线程函数)。
如果我使用互斥锁进行同步,并且线程A获取互斥锁并在while循环中增加'p',但它不会释放互斥锁。 所以我的问题是,如果线程A没有释放互斥锁,那么线程B可以访问变量'p'??
修改 线程B也受到使用互斥锁的'p'保护。
如果线程A使用pthread_mutex_lock()锁定,并且没有释放它,那么如果相同的线程(A)再次尝试访问锁定会发生什么(记住线程A在循环时) 例如
while(1)
{
pthread_mutex_lock(&mutex);
p = 10;
}
如果从未发布互斥锁,此代码是否有任何问题?
答案 0 :(得分:2)
您仍然可以访问线程B中的变量,因为互斥锁是一个未连接到变量的独立对象。如果在访问p
之前从线程B调用互斥锁,则线程B将等待释放互斥锁。事实上,线程A只会执行一次循环体,因为它会等待互斥锁被释放,然后才能再锁定它。
如果您没有解锁互斥锁,那么锁定相同互斥锁的任何调用都将无限期地等待,但该变量将是可写的。
在您的示例中,对变量p
的访问是所谓的临界区,或者是互斥锁和互斥锁版本之间的代码部分。
答案 1 :(得分:0)
对互斥锁没有限制,您需要编写程序以遵循使用互斥锁的规则。
以下是在共享资源上使用互斥锁的基本步骤:
如果A& B遵守规则,然后B不能修改它,而A保持锁定。
或者,如果你的线程B没有首先获得锁,那么它的原因可能会修改变量,但这将是并发编程的一个错误。
顺便说一句,你也可以将condition
与mutex
一起使用,这样你就可以让线程等待&相互通知,而不是一直循环,这是浪费机器资源。
有关您的更新问题
在linux上,在c中,主要有3种获取互斥锁的方法,当线程无法获取锁时会发生什么,取决于你使用哪种方法。
int pthread_mutex_lock(pthread_mutex_t * mutex );
如果它已经被另一个线程锁定,那么它会一直阻塞,直到解锁为止,
int pthread_mutex_trylock(pthread_mutex_t * mutex );
类似于pthread_mutex_lock(),但它不会阻止,而是返回错误EBUSY,
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout);
类似于pthread_mutex_lock(),但在返回错误ETIMEDOUT之前会等待超时,
答案 2 :(得分:-2)
静态初始化互斥锁的简单示例
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
static int p = 0;
static pthread_mutex_t locker = PTHREAD_MUTEX_INITIALIZER;
static void *
threadFunc(void *arg)
{
int err;
err = pthread_mutex_lock(&locker);
if (err != 0){
perror("pthread_mutex_lock failed");
exit(1);
}
p++;
err = pthread_mutex_unlock(&locker);
if (err != 0){
perror("pthread_mutex_unlock failed");
exit(1);
}
return NULL;
}
int
main(int argc, char *argv[])
{
pthread_t A, B;
pthread_create(&A, NULL, threadFunc, NULL);
pthread_create(&B, NULL, threadFunc, NULL);
pthread_join(A, NULL);
pthread_join(B, NULL);
printf("p = %d\n", p);
return 0;
}
为简洁起见,省略了对main的错误检查,但应该使用。如果你不释放互斥程序将永远不会完成,线程B永远不会被锁定。