永久互斥锁定导致死锁?

时间:2010-06-15 12:28:38

标签: mutex pthreads

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

我期望看到的输出是来自两个线程的“活”消息,每个消息一个(例如121212121212.但是我得到的是一个线程获得大多数锁(例如111111222222222111111111或仅1111111111111 ......)。 / p>

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

#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;
}

3 个答案:

答案 0 :(得分:2)

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

通常,线程会一直运行,直到他们必须等待资源或者他们耗尽量子(时间片)。

在没有资源争用且所有线程具有相同优先级的情况下,最公平的调度算法是在交换之前为每个线程提供相等的时间片。那是因为交换操作本身需要一些时间,所以你不想经常这样做(相对于线程所做的实际工作。

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

答案 1 :(得分:1)

这不是死锁,它甚至不是活锁。这仅仅是缺乏公平性的情况。如果这对您至关重要,您应该使用确保非饥饿的原语,例如:排队互斥。

答案 2 :(得分:0)

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