Обнаружение заблокированных потоков
У меня есть теория, касающаяся проблем при съемке асинхронного приложения (я использую CCR), и мне интересно, сможет ли кто-нибудь подтвердить мою логику.
Если многопоточное приложение на основе CCR, использующее число потоков по умолчанию (т.е. по одному на ядро), работает медленнее, чем то же приложение с двойным указанием потоков - означает ли это, что потоки блокируются где-то в коде
Что думаете? Является ли это быстрым и достоверным способом определить, были ли потоки случайно заблокированы?
4 ответа
Если это так, это означает, что ваш пул потоков исчерпан (т.е. у вас есть 2 потока, но вы асинхронно отложили 4 ввода-вывода или что-то в этом роде) - если ваша работа сильно связана с вводом-выводом, правило "один поток на ядро" не действительно не применимо.
Что вы подразумеваете под "медленнее"?
Если вы хотите автоматически обнаруживать заблокированные потоки, возможно, эти потоки должны послать сердцебиение, которое затем отслеживается каким-то монитором, но ваши возможности ограничены.
Дешевый способ узнать, блокируются ли потоки, - это узнать текущее системное время перед выполнением любой потенциально блокирующей операции, затем после операции и посмотреть, сколько времени прошло. Например, ожидая прибытия сообщения, измерьте, сколько времени поток был заблокирован в ожидании прибытия сообщения.
Если нет всегда более чем достаточно сообщений для обработки, потоки будут блокировать ожидание сообщения. Если у вас больше потоков, то у вас больше потенциальных генераторов сообщений (в зависимости от вашего дизайна), и поэтому потоки, ожидающие получения сообщений, с большей вероятностью будут иметь один готовый.
Точно одного потока к ЦП слишком мало, если вы не можете гарантировать, что всегда будет достаточно сообщений, поэтому ни одному потоку не придется ждать.
Я обнаружил, что для поддержания текучести системы с минимальными потоками, я делаю задачи, связанные с вводом / выводом, максимально лаконичными. Они просто отправляют данные из ввода-вывода в другой порт и больше не обрабатывают. Поэтому данные помещаются в очередь в другом месте для обработки контролируемым образом без вмешательства в задачу сбора данных как можно быстрее. Эта обработка может происходить в ExclusiveGroup Interleave, если есть общее состояние, о котором нужно подумать... и удобный побочный эффект заключается в том, что исключительные задачи никогда не будут связывать все потоки в Dispatcher (однако, я подозреваю, что, возможно, есть более изящные способы управления этим в API CCR)