linux 中的线程并发

Thread concurrency in linux

我是SO的初学者,所以如果问题不清楚,请告诉我。

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

        }

如果永远不会释放互斥体,这段代码有什么问题吗?

互斥量没有限制,你需要按照使用互斥量的规则编写你的程序。

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

  • 先获取锁
  • 做作业(A增加,B设定值)
  • 解除锁定,

如果A&B都遵守规则,则B不能修改,A保持锁。

或者,如果您的线程 B 没有先获取锁,它当然可以修改变量,但这将是并发编程的错误。

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


针对您更新的问题

在linux,在c中,获取mutex锁的方法主要有3种,线程获取不到锁怎么办取决于你用的是什么方法。

  • int pthread_mutex_lock(pthread_mutex_t * mutex );

如果它已经被另一个线程锁定,那么它会阻塞直到锁被解锁,

  • int pthread_mutex_trylock(pthread_mutex_t * mutex );

类似于pthread_mutex_lock(),但不会阻塞,而是return错误EBUSY,

  • int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout);

类似于pthread_mutex_lock(),但是在return错误之前会等待超时 ETIMEDOUT,

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

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

在您的示例中,对变量 p 的访问称为临界区,或者互斥锁定和互斥释放之间的代码部分。

静态初始化互斥量的简单示例

#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 将永远不会获得锁。