我不知道这里的问题是什么,但是当我在OS X上运行我的代码时,它运行正常但在Linux上我的程序将无法运行。
这是我的代码:
Thread() {
- some other code -
randLane1 = rand() % 16;
randLane2 = rand() % 16;
while(randLane1 == randLane2) {
randLane2 = rand() % 16;
}
pthread_mutex_lock(&mutexFineLock[randLane1]);
pthread_mutex_lock(&mutexFineLock[randLane2]);
// if Rouge picked a lane that has already been fired at, look for a free lane
while(Gallery->Get(randLane1) != white) {
pthread_mutex_unlock(&mutexFineLock[randLane1]);
randLane1 = rand() % 16;
pthread_mutex_lock(&mutexFineLock[randLane1]);
}
pthread_mutex_unlock(&mutexFineLock[randLane2]);
}
现在这里是踢球者,如果我移除pthread_mutex_lock(&mutexFineLock[randLane2]);
和pthread_mutex_unlock(&mutexFineLock[randLane2]);
,它将毫无问题地运行。但是导致错误的原因是什么?如果我只是打开和关闭一个没有死锁可能性的锁,那么问题是什么?
如果我将pthread_mutex_unlock(&mutexFineLock[randLane2]);
放在我的pthread_mutex_lock(&mutexFineLock[randLane2]);
之后,那将进一步加剧我的困惑。
注意:在我的代码pthread_mutex_unlock(&mutexFineLock[randLane2]);
中有一个目的,它被放下来执行上面代码中未显示的操作。我正在调试我的错误并意识到它甚至没有通过for循环。
如果有人知道我的问题在哪里,那就太棒了。
答案 0 :(得分:1)
示例:
第一个线程已锁定mutexFineLock [randLane1 = 13],然后是mutexFineLock [randLane2 = 12]并正常工作。
第二个线程锁定了mutexFineLock [randLane1 = 3]然后尝试锁定被锁定等待的mutexFineLock [randLane2 = 12]。
处理第一个线程时释放了mutexFineLock [randLane1 = 13],然后尝试锁定被第二个线程锁定的mutexFineLock [randLane1 = 13%16 = 3]。等待。
最后,每个人都因为僵局而等待。
当您解锁randLane2时,第二个线程不必等待,所以它可以正常工作。
这是一个问题。
答案 1 :(得分:1)
您自己创建了一个死锁。 (至少只要你没有向我们展示你的互斥定义)。
while(Gallery->Get(randLane1) != white) {
pthread_mutex_unlock(&mutexFineLock[randLane1]);
randLane1 = rand() % 16; <---------------- PHAIL
pthread_mutex_lock(&mutexFineLock[randLane1]);
}
如果randLane1
等于randLane2
,您会尝试重新锁定相同的互斥锁。
由于错误的锁定顺序而避免死锁
pthread_mutex_lock(&mutexFineLock[randLane2]);
pthread_mutex_lock(&mutexFineLock[randLane1]);
重试获得不同的lane1和2。 编辑:将randLane2更改为1。
while(Gallery->Get(randLane1) != white) {
pthread_mutex_unlock(&mutexFineLock[randLane1]);
randLane1 = rand() % 16;
while(randLane1 == randLane2) { // retry
randLane1 = rand() % 16;
}
pthread_mutex_lock(&mutexFineLock[randLane1]);
}
答案 2 :(得分:0)
死锁的经典插图。解锁的顺序不是锁定的相反顺序。 lock(m1); lock(m2); unlock(m1)
是一本直接来自灾难的书籍食谱。您应该始终以锁定的相反顺序解锁互斥锁(或其他锁)。