2012-05-11 4 views
0

В моем приложении (C++/Linux) иногда поток получает мьютекс (рекурсивный) при отмене. Это вызывает тупик, поскольку другие потоки также используют один и тот же мьютекс и не могут чтобы получить его.Как проверить, поддерживает ли поток mutex C++

Теперь можно проверить, заблокирован ли этот поток каким-либо мьютексом. Мой мотив состоит в том, чтобы очистить вручную, что поток заблокирован, а затем отменить нить.

Один из возможных способов - это поддерживать счетчик. Любой лучший подход будет также приветствуется ..

Заранее спасибо

+0

Что значит «отменить»? – Dani

+0

в потоках приложений отменяется (pthread_cancel) случайным образом .. проблема возникает, когда какой-либо поток блокирует мьютекс и отменяется ... не освобождая его. – tuban

+0

@tuban: Подсказка: это не случайно. У вас есть ошибка. –

ответ

4

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

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

Вместо того чтобы писать какие-либо взломы, вы должны исправить свою ошибку.

0

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

Подсказка: на C++ что единственное, что гарантировано будет выполнено в случае отказа (броска)? Деструктор.

У вас есть 2 варианта:

  1. Вы можете использовать C++ 11 или повысить lock_guard, который инкапсулирует нормальный семафор, но и обеспечивает безопасность исключений, и предназначены, чтобы избежать таких проблем, как у вас. Но это означает, что вам нужно изменить все приложение на использование C++ 11 или увеличить потоки вместо pthread.

  2. Вы можете освободить мьютекс в деструкторе.

Удачи вам!

1

Как правило, вам не следует использовать pthread_cancel() из-за таких проблем. Если вам нужно использовать его, вы должны использовать pthread_cleanup_push and pthread_cleanup_pop, чтобы гарантировать, что мьютекс разблокирован, если поток отменен.

Нет никакого способа гарантировать правильное выполнение, если его вызвали pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS), поэтому не делайте этого.

pthread_cancel() очень C-ish. Рассмотрите возможность использования Boost's thread interruption, поскольку вы программируете на C++. Это хорошо сработает с объектами фиксированной блокировки.

Смежные вопросы