Ответ 1
Твердое твердое тело в течение 4 дней. Я объявляю победу на этом. Ответ - "глупая ошибка пользователя" (см. Комментарии выше). Мьютекс должен быть разблокирован только потоком, который его блокировал. Спасибо, что согласились с ним.
Я сталкиваюсь со следующей ошибкой в непредсказуемое время в приложении связи на основе linux (arm):
pthread_mutex_lock.c:82: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.
Google раскрывает много ссылок на эту ошибку, но мало информации, которая кажется актуальной для моей ситуации. Мне было интересно, может ли кто-нибудь дать мне некоторые идеи о том, как устранить эту ошибку. Кто-нибудь знает об общей причине для этого утверждения?
Спасибо заранее.
Твердое твердое тело в течение 4 дней. Я объявляю победу на этом. Ответ - "глупая ошибка пользователя" (см. Комментарии выше). Мьютекс должен быть разблокирован только потоком, который его блокировал. Спасибо, что согласились с ним.
Я столкнулся с той же проблемой, и Google отправил меня сюда. Проблема с моей программой заключалась в том, что в некоторых ситуациях я не инициализировал мьютекс, прежде чем блокировать его.
Хотя утверждение в принятом ответе является законным, я думаю, что это не является причиной этого неудачного утверждения. Потому что ошибка сообщается на pthread_mutex_lock
(и не разблокирована).
Кроме того, как всегда, более вероятно, что ошибка находится в исходном коде программистов, а не компиляторе.
Хотя OP имеет свой ответ, я думал, что поделился бы своей проблемой, если бы у кого-то была такая же проблема.
Обратите внимание, что это утверждение находится в __pthread_mutex_lock
, а не в разблокировке. Это, по моему мнению, указывает на то, что большинство других людей, имеющих эту проблему, не отпирают мьютексы в другом потоке, чем тот, который его блокировал; они просто блокируют мьютекс, который был разрушен.
Для меня у меня был класс (пусть его называют Foo
), который зарегистрировал статическую функцию обратного вызова с каким-то другим классом (пусть назовет ее Bar
). Обратный вызов передавался ссылкой на Foo
и иногда блокировал/разблокировал мьютекс, который был членом Foo
.
Эта проблема возникла после того, как экземпляр Foo
был уничтожен, а экземпляр Bar
все еще использовал обратный вызов. Обратный вызов передавался ссылкой на объект, который больше не существовал и, следовательно, вызывал __pthread_mutex_lock в памяти мусора.
Заметьте, я использовал С++ 11 std::mutex
и std::lock_guard<std::mutex>
, но, поскольку я был в Linux, проблема была точно такой же.
Быстрый бит Googling, который я делал, часто обвиняет это в неправильной оптимизации компилятора. Достойное суммирование здесь. Возможно, стоит посмотреть на сборку, чтобы узнать, генерирует ли gcc правильный код.
Либо это, либо вам удается топать в памяти, используемой библиотекой pthread... эти проблемы довольно сложно найти.
У меня была такая же проблема
в моем случае внутри потока я соединял vertica db с odbc добавив следующую настройку в /etc/odbcinst.ini, я решил свою проблему. до сих пор не получая исключения.
[ODBC]
Threading = 1
кредитов: hynek
добавление Threading = 0 в файл /etc/odbcinst.ini исправлено эту проблему
Я только что пробился через это и подумал, что это может помочь другим. В моем случае проблема возникла в очень простом методе, который блокировал мьютекс, проверял переменную общего доступа и затем возвращался. Метод является переопределением базового класса, который создает рабочий поток.
Проблема в этом случае заключалась в том, что базовый класс создавал поток в конструкторе. Затем поток начал выполняться, и была вызвана реализация метода для производных классов. К сожалению, производный класс еще не завершил конструирование, и мьютекс в производном классе имел неинициализированные данные как владелец мьютекса. Это выглядело так, как будто на самом деле было заблокировано, когда это не так
Решение действительно простое. Добавьте защищенный метод в базовый класс с именем StartThread(). Это нужно вызывать в конструкторе производных классов, а не из базового класса.