Подтвердить что ты не робот

Ошибка утверждения мьютекса Pthread

Я сталкиваюсь со следующей ошибкой в ​​непредсказуемое время в приложении связи на основе linux (arm):

pthread_mutex_lock.c:82: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.

Google раскрывает много ссылок на эту ошибку, но мало информации, которая кажется актуальной для моей ситуации. Мне было интересно, может ли кто-нибудь дать мне некоторые идеи о том, как устранить эту ошибку. Кто-нибудь знает об общей причине для этого утверждения?

Спасибо заранее.

4b9b3361

Ответ 1

Твердое твердое тело в течение 4 дней. Я объявляю победу на этом. Ответ - "глупая ошибка пользователя" (см. Комментарии выше). Мьютекс должен быть разблокирован только потоком, который его блокировал. Спасибо, что согласились с ним.

Ответ 2

Я столкнулся с той же проблемой, и Google отправил меня сюда. Проблема с моей программой заключалась в том, что в некоторых ситуациях я не инициализировал мьютекс, прежде чем блокировать его.

Хотя утверждение в принятом ответе является законным, я думаю, что это не является причиной этого неудачного утверждения. Потому что ошибка сообщается на pthread_mutex_lock (и не разблокирована).

Кроме того, как всегда, более вероятно, что ошибка находится в исходном коде программистов, а не компиляторе.

Ответ 3

TL;DR: убедитесь, что вы не блокируете мьютекс, который был уничтожен/не был инициализирован.

Хотя OP имеет свой ответ, я думал, что поделился бы своей проблемой, если бы у кого-то была такая же проблема.

Обратите внимание, что это утверждение находится в __pthread_mutex_lock, а не в разблокировке. Это, по моему мнению, указывает на то, что большинство других людей, имеющих эту проблему, не отпирают мьютексы в другом потоке, чем тот, который его блокировал; они просто блокируют мьютекс, который был разрушен.

Для меня у меня был класс (пусть его называют Foo), который зарегистрировал статическую функцию обратного вызова с каким-то другим классом (пусть назовет ее Bar). Обратный вызов передавался ссылкой на Foo и иногда блокировал/разблокировал мьютекс, который был членом Foo.

Эта проблема возникла после того, как экземпляр Foo был уничтожен, а экземпляр Bar все еще использовал обратный вызов. Обратный вызов передавался ссылкой на объект, который больше не существовал и, следовательно, вызывал __pthread_mutex_lock в памяти мусора.

Заметьте, я использовал С++ 11 std::mutex и std::lock_guard<std::mutex>, но, поскольку я был в Linux, проблема была точно такой же.

Ответ 4

Быстрый бит Googling, который я делал, часто обвиняет это в неправильной оптимизации компилятора. Достойное суммирование здесь. Возможно, стоит посмотреть на сборку, чтобы узнать, генерирует ли gcc правильный код.

Либо это, либо вам удается топать в памяти, используемой библиотекой pthread... эти проблемы довольно сложно найти.

Ответ 5

У меня была такая же проблема

в моем случае внутри потока я соединял vertica db с odbc добавив следующую настройку в /etc/odbcinst.ini, я решил свою проблему. до сих пор не получая исключения.

[ODBC]
Threading = 1

кредитов: hynek

Ответ 6

добавление Threading = 0 в файл /etc/odbcinst.ini исправлено эту проблему

Ответ 7

Я только что пробился через это и подумал, что это может помочь другим. В моем случае проблема возникла в очень простом методе, который блокировал мьютекс, проверял переменную общего доступа и затем возвращался. Метод является переопределением базового класса, который создает рабочий поток.

Проблема в этом случае заключалась в том, что базовый класс создавал поток в конструкторе. Затем поток начал выполняться, и была вызвана реализация метода для производных классов. К сожалению, производный класс еще не завершил конструирование, и мьютекс в производном классе имел неинициализированные данные как владелец мьютекса. Это выглядело так, как будто на самом деле было заблокировано, когда это не так

Решение действительно простое. Добавьте защищенный метод в базовый класс с именем StartThread(). Это нужно вызывать в конструкторе производных классов, а не из базового класса.