Форум: "Основная";
Текущий архив: 2006.05.14;
Скачать: [xml.tar.bz2];
ВнизTThread и "пожирание" процессорного времени Найти похожие ветки
← →
sally (2006-04-06 14:26) [0]Сделал простейший наследник от TThread.
TMyThread = class(TThread)
public
procedure Execute; override;
constructor Create(CreateSuspended: Boolean);
end;
constructor TMyThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
Priority := tpLowest;
Resume;
end;
procedure TMyThread.Execute;
var
i: integer;
begin
inherited;
ReturnValue := 0;
for i := 0 to MaxInt do
ReturnValue := ReturnValue + i + i * i + i * i * i;
end;
Просто для примера. При запуске, пожиравет все 100% CPU. А ведь Priority стоит tpLowest. Как добиться того, чтобы он кушал чуть-чуть :) ?
← →
Рамиль © (2006-04-06 14:31) [1]Ну и будет кушать, если процу нечем больше занятся. Так и должно быть.
← →
MBo © (2006-04-06 14:31) [2]>При запуске, пожиравет все 100% CPU
Ну правильно, ты ведь задал поточной функции работать на всю катушку.
inherited, кстати, убери (оно ничего не делает)
А для того, чтобы получеть дельный совет, нужно описать реальную задачу.
← →
Sally (2006-04-06 14:36) [3]>MBo
>inherited, кстати, убери
И получить рекурсию...
Реальная задача состоит в том, чтобы сканировать диск на наличие определенных файлов.
← →
Юрий Зотов © (2006-04-06 14:41) [4]> Sally (06.04.06 14:36) [3]
>> MBo
>> inherited, кстати, убери
> И получить рекурсию...
Каким же образом?
← →
MBo © (2006-04-06 14:43) [5]>inherited, кстати, убери
>И получить рекурсию...
Какие ваши доказательства? (© Red heat)
:)
TThread
procedure Execute; virtual; abstract;
← →
Sally (2006-04-06 14:44) [6]>Юрий Зотов
Ну как.
constructor TMyThread.Create(CreateSuspended: Boolean);
begin
Create(CreateSuspended);
Здесь он сам себя будет вызывать....
← →
Sally (2006-04-06 14:45) [7]Не разобралиь в какой строчке :)
← →
Sally (2006-04-06 14:47) [8]И все таки каким образом можно уменьшить нагрузку?
Даже в этом простом примере? Мне принцип важен.
← →
Сергей М. © (2006-04-06 15:04) [9]
> принцип важен
Принцип прост - не реже чем 1 раз за итерацию твоего for-цикла передавать управление системе, вызывая, скажем, sleep(0) .. Чем чаще ты это будешь делать, тем меньше твой поток будет "пожирать"
← →
Юрий Зотов © (2006-04-06 15:05) [10]> Sally (06.04.06 14:47) [8]
> каким образом можно уменьшить нагрузку?
Она уже уменьшена, ничего уменьшать уже не надо. Процессору нечего делать, вот он и крутит Ваш поток, несмотря на его низкий приоритет. Как только появится поток с более высоким приоритетом, он будет обслуживаться в первую очередь, а уж потом - Ваш. Причем это легко проверить, создав такой поток самому.
Впрочем, нагрузку можно еще уменьшить, понизив базовый приоритет потока (то есть, приоритет процесса, от которого и отсчитываются приоритеты его потоков - см. SetPriorityClas), но надо иметь в виду, что это понизит приоритет ВСЕХ потоков Вашей программы, включая и главный.
← →
MBo © (2006-04-06 15:07) [11]Я говорил об inherited в Execute.
А в конструкторе - нормально.
>Даже в этом простом примере?
Пример бессмысленный. Хотя загрузку можно уменьшить, вставив в цикл Sleep, без реально поставленной задачи говорить пока не о чем
← →
Sally (2006-04-06 15:11) [12]Реальная задача состоит в том, чтобы сканировать диск на наличие определенных файлов.
← →
Юрий Зотов © (2006-04-06 15:40) [13]> Sally (06.04.06 15:11) [12]
Тогда, возможно, нужно идти немного другим путем - не понижать приоритет потока, а усыпить его совсем до получения уведомления от системы. См. FindFirstChangeNotification и родственные ей функции.
← →
sally (2006-04-06 15:56) [14]>Юрий Зотов
Спасибо. Не подойдет, т.к. нужно запустить и просканировать диск.
На C аналогичный результат будет по загруженности процессора? (Нет под рукой Visual Studio). Или если на чистом API это все оформить. Просто есть приложения на С(в частности WinDefrag) который сканирует файлы на диске, но при этом кушает всего ничего. Или взять стандартный Дефрагментатов. Тоже ведь сканирует диск и при этом также не кушает много.
← →
Юрий Зотов © (2006-04-06 16:27) [15]С, Delphi, API - какая разница? Все равно все сведется все к тем же вызовам API. Тут дело не в языке, а в алгоритме. Например, понизить приоритет до Idle и пусть работает только при простое системы. Или, если есть цикл, то вызывать Sleep(0), как советовали.
← →
Sally (2006-04-06 16:32) [16]ок. понял. всем спасибо
← →
Сергей М. © (2006-04-06 17:05) [17]
> Sally (06.04.06 16:32) [16]
Еще "круче" будет применение вместо Sleep()вызова MsgWaitForMultipleObjects(), который даст возможность, с одной стороны, переводить поток в kernel-time на указанное время (тоже самое что делает sleep), а с другой - реагировать на сообщения потоку и его окнам.
Но это - не твой случай, судя по абстракции, приведенной тобой, а не реальности, которую пытался стребовать с тебя ув. MBo © (06.04.06 14:31) [2]
← →
Tirael © (2006-04-07 01:36) [18]кстати по одной умной книжке перевод потока в режим ядра занимает около 1000 тактов процессора, так что насчет бесполезной траты наверное всетаки лучше просто понизить приоритет
← →
Германн © (2006-04-07 01:44) [19]
> Tirael © (07.04.06 01:36) [18]
>
> кстати по одной умной книжке перевод потока в режим ядра
> занимает около 1000 тактов процессора, так что насчет бесполезной
> траты наверное всетаки лучше просто понизить приоритет
А сколько это в миллисекундах? :-)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.05.14;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.009 c