2010-09-18 7 views
2

У меня есть программа с основная резьба и диагностика нить. Основной поток - это в основном цикл while(1), который выполняет различные задачи. Одна из этих задач - предоставить механизм диагностики с информацией о системе, а затем проверить ее позже (т. Е. В следующем цикле), чтобы увидеть, есть ли какие-либо проблемы, с которыми нужно бороться. Итерация основного контура должна занимать не более 0,1 секунды. Если все в порядке, тогда у диагностического механизма почти нет времени, чтобы вернуться с ответом. Однако, если есть проблема, механизм диагностики может занять несколько секунд, чтобы изолировать проблему. По этой причине каждый раз, когда диагностический движок получает новую информацию, он закручивает новый поток диагностики.Boost threads: возможно ли ограничить время работы нитки, прежде чем переходить на другую резьбу

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

Использование потоков Boost, можно ли ограничить время, в течение которого поток может работать, прежде чем переходить к другому потоку? Также важно отметить, что используемый нами алгоритм диагностики является черным ящиком, поэтому мы не можем помещать в него какой-либо код. Благодаря!

ответ

1

Если запустить несколько потоков, они действительно потребляют процессорного времени. Если у вас только один процессор, а один поток выполняет интенсивную работу с процессором, то этот поток замедлит работу, выполняемую другими потоками. Если вы используете объекты, специфичные для ОС, чтобы изменить приоритет потока, то вы можете сделать диагностический поток более низким приоритетом, чем основной поток. Кроме того, вы отмечаете, что диагностический поток «вращается».Вы имеете в виду, что в буквальном смысле имеет эквивалент спин-ждать, как это:

while(!check_done()) ; // loop until done 

Если да, то я настоятельно рекомендую вам попробовать и избежать такой занят, подождите, как он будет потреблять процессорное время, не добившись ничего ,

Однако, хотя несколько потоков могут привести к замедлению друг друга, если вы видите фактическую задержку в несколько секунд, это может означать, что есть еще одна проблема, и что основной поток действительно ждет завершения диагностического потока , Убедитесь, что вызов для join() для диагностического потока находится за пределами основного цикла.

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

Чтобы действительно помочь, мне нужно будет увидеть код.

0

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

Boost.Thread не поддерживает приоритеты потоков, хотя ваш API-интерфейс, специфичный для конкретной ОС. Однако ваша проблема, по-видимому, указывает на необходимость фундаментального редизайна - или, по крайней мере, тяжелого профилирования, чтобы найти узкие места.

+0

С тех пор, как я * очень хорошо разбираюсь в программировании потоков, есть вероятность, что я неправильно понимаю вещи. Однако приведенный вами пример скорее всего является плохим выбором в словах. Если у меня есть нить A и нить B, я бы ожидал, что ОС будет быстро переключаться между A и B, чтобы пользователь GUI в потоке A обнаружил, что A всегда включен. В моем случае кажется, что ОС разрешает поток B работать в течение 2 секунд, прежде чем переключиться обратно в поток A. Почему это должно быть? (Также скажите мне, если я все еще запутался в какой-то проблеме с потоками.) – JnBrymn

+0

Темы не будут блокироваться. Ваша ОС не должна допускать этого. Однако для определения фактического времени, затраченного в каждом потоке, должно быть возможно использовать профилировщик. – rlbond

+0

Я никогда не использовал профилировщик. Любые рекомендации? Моя IDE - это Eclipse CDT, и я использую цепочку инструментов gnu (gcc, g ++, make, gdb). – JnBrymn

0

Вы не можете делать это вообще на уровне ОС, поэтому я сомневаюсь, что у boost есть что-то конкретное для ограничения времени выполнения. Вы можете подделать его с помощью небольших блоков и ждать, но это не чисто.

Я бы предложил посмотреть на сродство к процессору либо на уровне потока, либо на уровне процесса (это будет специфично для ОС). Если вы можете изолировать вашу диагностическую обработку до ограниченного подмножества [логических] процессоров на многоядерной машине, это даст вам очень курсный механизм для управления максимальным количеством выполнения по сравнению с основным процессом. Это лучшее решение, которое я нашел при попытке сделать подобный тип вещей.

Надеюсь, что это поможет.

2

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

, чтобы проверить, что это ничего не связано с ОС планирования запуска запрограммированной на двойной базовой системе, так что обе нити могут быть выполнены на самом деле параллельно

+0

Это то, о чем я думал, но во время основного цикла я запрашиваю диагностический цикл, чтобы узнать, занят ли он уже занятым. Когда он занят, я печатаю это сообщение на экране. В случае, когда моя программа висит, я вижу, по крайней мере, один, но иногда несколько сообщений «Диагностические потоки заняты». Возможно, это все еще что-то еще, но я думаю, что если проверка вернется как * занятая *, то я не буду делать ничего другого, что помешало бы этому потоку. – JnBrymn

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