Поток вызывает неожиданный сбой

Я понятия не имею, в чем здесь проблема, но когда я запускаю свой код в 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

Решение

Пример:

Первый поток заблокировал mutexFineLock [randLane1 = 13], затем mutexFineLock [randLane2 = 12] и работает.

Второй поток заблокировал mutexFineLock [randLane1 = 3], затем пытается заблокировать mutexFineLock [randLane2 = 12], который заблокирован, в ожидании.

Во время обработки первый поток выпустил mutexFineLock [randLane1 = 13], а затем пытается заблокировать mutexFineLock [randLane1 = 13% 16 = 3], который заблокирован вторым потоком. Ожидание.

Наконец-то все ждут из-за тупика.

При разблокировке randLane2 сразу второй поток не должен ждать, поэтому он работает нормально.

Это проблема.

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]);

Повторите попытку, чтобы получить другую полосу 1 и 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]);
}
1

Классическая иллюстрация тупика. Порядок разблокировки не является обратным порядком блокировки. lock(m1); lock(m2); unlock(m1) это прямой рецепт катастрофы. Вы должны всегда разблокировать мьютексы (или другие блокировки) в порядке, обратном их блокировке.

0
По вопросам рекламы [email protected]