我遇到了互斥锁(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;
}
答案 0 :(得分:2)
您误解了互斥锁的工作方式(至少在您的特定实现中)。释放互斥锁不会自动交换到正在等待它的另一个线程。
通常,线程会一直运行,直到他们必须等待资源或者他们耗尽量子(时间片)。
在没有资源争用且所有线程具有相同优先级的情况下,最公平的调度算法是在交换之前为每个线程提供相等的时间片。那是因为交换操作本身需要一些时间,所以你不想经常这样做(相对于线程所做的实际工作。
如果要在线程之间交替,则需要比互斥锁更具确定性的东西,例如一组条件变量:
答案 1 :(得分:1)
这不是死锁,它甚至不是活锁。这仅仅是缺乏公平性的情况。如果这对您至关重要,您应该使用确保非饥饿的原语,例如:排队互斥。
答案 2 :(得分:0)
当第一个线程解锁互斥锁时,在该更改可用于另一个线程之前,当然会有一些延迟。这可能比第一个线程重新锁定互斥锁的时间要长,因为它不必等待这段时间。