我遇到了一个互斥锁的问题(Linux上的pthread_mutex),如果一个线程在解锁一个互斥锁之后再次锁住它,那么另一个线程就不能很成功地获得锁。我已经附加了测试代码,其中创建了一个互斥锁,以及两个在无限循环中锁定互斥锁的线程,休眠一段时间,然后再次解锁。
我希望看到的输出是来自两个线程的“活动”消息,每个线程都有一个消息(例如121212121212。然而,我得到的是,一个线程获得了大多数锁(例如111111222222222111111111或1111111111111...)。
如果我在解锁之后添加一个usleep(1),一切都会正常工作。显然,当线程进入休眠状态时,另一个线程会获得它的锁--然而,这不是我所期望的方式,因为另一个线程已经调用了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;
}发布于 2010-06-15 20:45:05
您误解了互斥锁的工作方式(至少在您的特定实现下)。互斥锁的释放不会自动交换到等待它的另一个线程。
通常,线程会一直运行,直到它们必须等待资源或耗尽它们的时间片为止。
在没有资源争用且所有线程都具有相同优先级的情况下,最公平的调度算法是在交换之前为每个线程分配相等的时间片。这是因为交换操作本身需要一些时间,所以您不希望频繁地执行该操作(相对于由线程完成的实际工作)。
如果你想在线程之间交替,你需要一些比互斥锁更具确定性的东西,比如一组条件变量:
发布于 2010-06-15 20:45:37
这不是死锁,甚至不是活锁。这只是一个缺乏公正性的案例。如果这对你来说很重要,你应该使用确保非饥饿的原语,例如队列互斥。
发布于 2010-06-15 21:00:33
当第一个线程解锁互斥锁时,当然会有一些延迟,然后更改才会对另一个线程生效。这可能比第一线程重锁互斥锁所花费的时间更长,因为它这次不必等待。
https://stackoverflow.com/questions/3045066
复制相似问题