【问题标题】:Permanent mutex locking causing deadlock?永久互斥锁导致死锁?
【发布时间】:2011-03-03 23:17:24
【问题描述】:

我遇到了互斥锁的问题(Linux 上的 pthread_mutex),如果一个线程在解锁后立即再次锁定互斥锁,另一个线程不是很成功地获得锁。我附上了创建一个互斥锁的测试代码,以及两个线程,它们在无限循环中锁定互斥锁,休眠一段时间并再次解锁。

我希望看到的输出是来自两个线程的“活动”消息,每个线程一个(例如 121212121212。​​但是我得到的是一个线程获得了大多数锁(例如 111111222222222111111111 或只是 1111111111111...)。

如果我在解锁后添加一个 usleep(1),一切都会按预期工作。显然,当线程进入 SLEEP 时,另一个线程获得了它的锁——但这不是我所期望的方式,因为另一个线程已经调用了 pthread_mutex_lock。我怀疑这是实现的方式,因为动作线程具有优先级,但是它在这个特定的测试用例中会导致某些问题。有什么方法可以防止它(除了故意添加足够大的延迟或某种信号)或者我的理解错误在哪里?

#include <pthread.h>
#include <stdio.h>

#include <string.h>
#include <sys/time.h>
#include <unistd.h>

pthread_mutex_t mutex;

void* threadFunction(void *id) {
 int count=0;

 while(true) {
  pthread_mutex_lock(&mutex);
  usleep(50*1000);
  pthread_mutex_unlock(&mutex);
  // usleep(1);

  ++count;
  if (count % 10 == 0) {
   printf("Thread %d alive\n", *(int*)id);
   count = 0;
  }
 }

 return 0;
}

int main() {
 // create one mutex
 pthread_mutexattr_t attr;
 pthread_mutexattr_init(&attr);
 pthread_mutex_init(&mutex, &attr);

 // create two threads
 pthread_t thread1;
 pthread_t thread2;

 pthread_attr_t attributes;
 pthread_attr_init(&attributes);

 int id1 = 1, id2 = 2;
 pthread_create(&thread1, &attributes, &threadFunction, &id1);
 pthread_create(&thread2, &attributes, &threadFunction, &id2);

 pthread_attr_destroy(&attributes);

 sleep(1000);
 return 0;
}

【问题讨论】:

    标签: mutex pthreads


    【解决方案1】:

    您误解了互斥锁的工作方式(至少在您的特定实现下)。互斥锁的释放不会自动交换到另一个正在等待它的线程。

    通常,线程会一直运行,直到它们必须等待资源或用完它们的时间片(时间片)。

    在没有资源争用且所有线程具有相同优先级的情况下,最公平的调度算法是在交换之前给每个线程相等的时间片。那是因为交换操作本身需要一些时间,所以您不希望过于频繁地执行此操作(相对于线程正在完成的实际工作。

    如果你想在线程之间交替,你需要比互斥锁更具确定性的东西,比如一组条件变量:

    【讨论】:

    • 我希望其他线程的锁调用会被注册并导致当前正在运行的线程的锁不成功(即排队的互斥锁)。由于这是一个人为的测试用例,实际上并没有在我的应用程序中发生,所以我将保留它,但如果再次出现此问题,请记住您的答案。
    【解决方案2】:

    这不是死锁,甚至不是活锁。这只是缺乏公平的情况。如果这对您很重要,您应该使用确保非饥饿的原语,例如一个队列互斥体。

    【讨论】:

      【解决方案3】:

      当第一个线程解锁互斥锁时,在其他线程可以使用该更改之前当然会有一些延迟。这可能比第一个线程重新锁定互斥锁所需的时间要长,因为这一次它不必等待。

      【讨论】:

        猜你喜欢
        • 2014-05-24
        • 1970-01-01
        • 2015-10-26
        • 2012-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多