Как правило, если задача1 удерживает блокировку A, хочет захватить блокировку B, а другая задача2 взяла блокировку B и ожидает блокировки A, удерживаемой задачей1), это вызывает тупик.
Но когда дело доходит доpthread_mutex_timedlock, он пытается выполнить блокировку мьютекса или тайм-аут после указанного тайм-аута.
Я попал в сценарий тупиковой ситуации, в котором я пытался взять тайм-блокировку, которая в конечном итоге истекла бы, что озадачивает меня.1006 * edit: можно избежать тупиков, имея лучший дизайн, что я и сделал в итоге, я убедился, что порядок взятия блокировок мьютекса одинаков, чтобы избежать тупиков, но остается открытым вопрос о том,тупика можно избежать, так как я выбрал временную блокировку
Может кто-нибудь объяснить мне это поведение?
Редактировать: Прикрепить пример кода, чтобы сделать сценарий более ясным (реальные задачи довольносложный и работает в тысячи строк)
T1
pthread_mutex_lock(&lockA);
//call some API, which results in a lock of m2
pthread_mutex_lock(&lockB);
//unlock in the order
pthread_mutex_unlock(&lockB);
pthread_mutex_unlock(&lockA);
T2
pthread_mutex_lock(&lockB);
//call some API, which results in locking m1
pthread_mutex_timedlock(&lockA,<10 sec>);
Авария видна вконтекст T2, bt:
Program terminated with signal 6, Aborted.
#0 0x57edada0 in raise () from /lib/libc.so.6
(gdb) bt
#0 0x57edada0 in raise () from /lib/libc.so.6
#1 0x57edc307 in abort () from /lib/libc.so.6
#2 0x57ed4421 in __assert_fail () from /lib/libc.so.6
#3 0x57bb2a7c in pthread_mutex_timedlock () from /lib/libpthread.so.0
Я проследил ошибку до следующего
pthread_mutex_timedlock: Assertion `(-(e)) != 35 || (kind != PTHREAD_MUTEX_ERRORCHECK_NP && kind != PTHREAD_MUTEX_RECURSIVE_NP)' failed.