Я понятия не имею, в чем здесь проблема, но когда я запускаю свой код в 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.
Если у кого-то есть идея, в чем мои проблемы, это было бы здорово.
Пример:
Первый поток заблокировал mutexFineLock [randLane1 = 13], затем mutexFineLock [randLane2 = 12] и работает.
Второй поток заблокировал mutexFineLock [randLane1 = 3], затем пытается заблокировать mutexFineLock [randLane2 = 12], который заблокирован, в ожидании.
Во время обработки первый поток выпустил mutexFineLock [randLane1 = 13], а затем пытается заблокировать mutexFineLock [randLane1 = 13% 16 = 3], который заблокирован вторым потоком. Ожидание.
Наконец-то все ждут из-за тупика.
При разблокировке randLane2 сразу второй поток не должен ждать, поэтому он работает нормально.
Это проблема.
Вы создаете тупик с самим собой. (по крайней мере, пока вы не покажете нам свое определение мьютекса).
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]);
}
Классическая иллюстрация тупика. Порядок разблокировки не является обратным порядком блокировки. lock(m1); lock(m2); unlock(m1)
это прямой рецепт катастрофы. Вы должны всегда разблокировать мьютексы (или другие блокировки) в порядке, обратном их блокировке.