2010-03-07 4 views
4

В основном у меня есть серверная программа C# (консольное приложение не в IIS), которое иногда входит в тупик.Как я могу найти причину тупика в многопоточной программе C#?

Странно, когда я прикрепляю отладчик, я вижу 3 потока, ожидающих блокировки, но без потоков (используя окно потоков в визуальной студии) внутри замка! Что здесь происходит ... Я думаю, что отладчик визуальной студии лежит.

Но так или иначе ... какие методы или инструменты следует использовать?

Благодаря

+2

Какой замок они ждут? Что вы видите в столах вызовов? – SLaks

ответ

5

Я хотел бы начать с отправки Трассировочная каждый раз, когда нить собирается войти/оставить критическую секцию, а также каждый раз, когда он успешно приобретает замок. Используйте класс System.Diagnostics.Trace.

Тогда вы должны быть способны определить из вашего вывода трассировки, в котором на самом деле есть блокировка.

Типичный код трассировки:

Trace.WriteLine("Acquiring lock - foo"); 
lock (foo) 
{ 
    Trace.WriteLine("Acquired lock - foo"); 
    // Do some stuff 
    Trace.WriteLine("Releasing lock - foo"); 
} 
Trace.WriteLine("Released lock - foo"); 

В зависимости от способа ваша программа структурирована, это не могло бы быть полезным, если не включать информацию о нити в трассировке, например:

Trace.WriteLine(string.Format("Thread {0} - Acquiring lock - foo", 
    Thread.CurrentThread.ManagedThreadId)); 

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

1

Вы также можете использовать WinDbg с SOS.dll, чтобы узнать, где находится тупик. Посмотрите на статью this. Команда SOS.dll, о которой идет речь, является! Syncblk - она ​​просматривает потоки .NET, которые ищут информацию о возможных взаимоблокировках.

+0

Обратите внимание, что на самом деле существует больше сценариев взаимоблокировок, поскольку вызовы между процессами и т. Д. Также могут приводить к взаимоблокировкам. Но анализ дампов всегда является хорошим началом. –

0

У вас, вероятно, есть состояние гонки с вашими нитями. Один из ваших потоков не отказывается от блокировки, и он не использует его или не позволяет кому-либо использовать его. Это также происходит, когда поток имеет блокировку и убит, прежде чем отказаться от него. Возможно, вам захочется проверить какие-либо программные решения для тупика, такие как «Спящий парикмахер», «Хлебопекарня Лампорта», «Алгоритм Деккера», «Алгоритм Петерсона» или «Обеденные философы».

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

2

Всегда есть WinDbg, но кривая обучения может быть немного сложной.

Но увидеть Brians отличный ответ на этот вопрос: Detecting deadlocks in a C# application

+0

@ Luhmann - эта ссылка очень хорошая. Очень хорошее описание использования WinDbg. –

0

Одним словом, Chess, программа от Microsoft для оказания помощи решить именно эти виды проблем.

С их сайта:

ШАХМАТЫ неоднократно запускает параллельную тест, обеспечивающий, что каждый прогон занимает другое чередование. Если чередование приводит к ошибке, CHESS может воспроизводить чередование для улучшения отладки. CHESS - , доступный как для управляемых, так и для родных программ .

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