linux

时间:2015-06-19 10:39:46

标签: c pthreads mutex

我是初学者,所以如果问题不明确,请告诉我。

我使用两个线程,例如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;

        }

如果从未发布互斥锁,此代码是否有任何问题?

3 个答案:

答案 0 :(得分:2)

您仍然可以访问线程B中的变量,因为互斥锁是一个未连接到变量的独立对象。如果在访问p之前从线程B调用互斥锁,则线程B将等待释放互斥锁。事实上,线程A只会执行一次循环体,因为它会等待互斥锁被释放,然后才能再锁定它。

如果您没有解锁互斥锁,那么锁定相同互斥锁的任何调用都将无限期地等待,但该变量将是可写的。

在您的示例中,对变量p的访问是所谓的临界区,或者是互斥锁和互斥锁版本之间的代码部分。

答案 1 :(得分:0)

对互斥锁没有限制,您需要编写程序以遵循使用互斥锁的规则。

以下是在共享资源上使用互斥锁的基本步骤:

  • 首先获得锁定
  • 做工作(A增加,B设定值)
  • 解锁,

如果A& B遵守规则,然后B不能修改它,而A保持锁定。

或者,如果你的线程B没有首先获得锁,那么它的原因可能会修改变量,但这将是并发编程的一个错误。

顺便说一句,你也可以将conditionmutex一起使用,这样你就可以让线程等待&相互通知,而不是一直循环,这是浪费机器资源。

有关您的更新问题

在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永远不会被锁定。