线程导致意外崩溃

时间:2015-11-10 14:18:44

标签: c++ multithreading locks

我不知道这里的问题是什么,但是当我在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循环。

如果有人知道我的问题在哪里,那就太棒了。

3 个答案:

答案 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)是一本直接来自灾难的书籍食谱。您应该始终以锁定的相反顺序解锁互斥锁(或其他锁)。