unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Contnrs;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private{ Private declarations }public{ Public declarations }end;
type TMyThread=class(TThread)
procedure Execute;override;
public
procedure TimeUpdate ;
end;
var
Form1: TForm1;
ThreadList:TObjectList;
implementation{$R *.dfm}procedure TMyThread.TimeUpdate ;
begin
Form1.Label1.Caption :=TimeToStr(Time);
end;
Procedure TMyThread.Execute ;
begin
while not self.Terminated do
begin
Synchronize(TimeUpdate);
Application.ProcessMessages ;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var t:TMyThread;
begin
t:= TMyThread.Create(true);
t.Resume ;
ThreadList.Add(t) ;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ThreadList:=TObjectList.Create(true);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ThreadList.Destroy ;
end;
end.
проблема такая добавляем штук 5 потоков по кнопке ,
всё работает, однако в диспетчере процессов показывает загрузку ЦП 98%
ничего не лагает вроде
почему такая штука, где косякъ?
в доках написано , что не рекомендуется больше вроде 14 потоков на однопроцессорной системе,
но ето ж гонево сколько хочу столько и ворочу,раньше делал не было таких проблем
Здравствуйте, par, Вы писали:
par>Procedure TMyThread.Execute ; par>begin par>while not self.Terminated do par>begin par> Synchronize(TimeUpdate); par> Application.ProcessMessages ; par>end; par>end;
Сто раз обсуждали ведь уже. Цикл крутится -> процессор занят. Самое простое в данном случае на мой взгляд — вызывать всё время Sleep(1). Загрузка проца сразу упадёт.
И ещё: Application.ProcessMessages здесь ни к селу ни к городу.
Здравствуйте, ak_miass, Вы писали:
_>Сто раз обсуждали ведь уже. Цикл крутится -> процессор занят. Самое простое в данном случае на мой взгляд — вызывать всё время Sleep(1). Загрузка проца сразу упадёт.
Лучше Sleep (1000)
_>И ещё: Application.ProcessMessages здесь ни к селу ни к городу.
Я бы сказал совсем не к месту Может даже к крешу привести...
Здравствуйте, Danchik, Вы писали: _>>Сто раз обсуждали ведь уже. Цикл крутится -> процессор занят. Самое простое в данном случае на мой взгляд — вызывать всё время Sleep(1). Загрузка проца сразу упадёт. D>Лучше Sleep (1000)
Неважно. Можно и Sleep(0). Главное — отдать остаток слайса. Остальной код цикла обычно занимает пренебрежимо малую долю слайса.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
D>>Лучше Sleep (1000) S>Неважно. Можно и Sleep(0). Главное — отдать остаток слайса. Остальной код цикла обычно занимает пренебрежимо малую долю слайса.
Согласен, просто пошутил
Здравствуйте, ak_miass, Вы писали:
par>> Synchronize(TimeUpdate);
_>Сто раз обсуждали ведь уже. Цикл крутится -> процессор занят.
О чем вообще разговор? Тормозов нет, в чем проблема? В загрузке? Загрузка будет 100% даже с одним потоком, даже если вызывать в нем Sleep(0). И то сказать — если проц больше никому и не нужен, понятно, что мы на нем развернемся по максимуму: хоть мы и отдаем отстатки квантов, все равно все кванты идут нам. Вот Sleep(10) — уже другой разговор.
А Application.ProcessMessages в данном случае, кстати, помогает избежать "подвисания" (кажущегося) главной формы. То есть если его убрать, при 3-4 потоках она подвисает. Соль тут, видимо, в упускании кванта во время PeekMessage (хотя по логике вещей эта функция не блокирующая). Разумеется, на самом деле никаких сообщений при вызове из другого потока Application.ProcessMessages не поймает, да и вообще борланд не гарантирует в этом случае нормальную работу. Если на то пошло, лучше вместо нее вызывать просто PeekMessage или вообще просто Sleep (она-то уж точно блокирующая).
А внешний эффект без ProcessMessages — подвисание — объясняется тем, что при трех-четырех и более потоках основное окно перестает двигаться и т.п. — ну так это потому, что VCL-поток закидывают Synchronize'ами, и он не успевает нормальные оконные сообщения обрабатывать. Лучше пореже кидать Synchronize.
par>> в доках написано , что не рекомендуется больше вроде 14 потоков на однопроцессорной системе Любое мало-мальски сложное приложение (работающее с ADO, COM или с RAS) уже цепляет к себе около 7-8 лишних потоков. Правда, не все они все время работают (видимо, часть задействована под пул), но сие высказывание из доков всеж-таки звучит смешно
Slicer
Специалист — это варвар, невежество которого не всесторонне :)
А вот за это можно получить от системы сапогом по мягкому месту, и довольно быстро.
Почему поток лезет грязными руками к полям VCL-объектов? VCL НЕ ЯВЛЯЕТСЯ ПОТОКОБЕЗОПАСНОЙ БИБЛИОТЕКОЙ
Единственное, что должен делать тут поток — это PostMessage(Form1.Handle, ...);
В сообщении нужно передавать через WParam/LParam все необходимые данные (или ссылку на объект, если места не хватает)
А уже на форме обработчик этого события в контексте визуального потока (а не нашего TMyThread) успешно поменяет Caption.
Далее. Вместо цикла с ProcessMessage делай WaitForSingleObject или любую другую Wait-функцию. Поставь таймаут 500 мс, этого должно хватить. Ждать лучше экземпляр TEvent, так проще всего. WaitForSingleObject выстрелит сама по истечении таймаута или по команде TEvent.SetEvent
Ресурсы процессора это нагружает минимально.
Re[2]: потоки и загрузка процессора...
От:
Аноним
Дата:
23.04.05 21:19
Оценка:
Здравствуйте, ak_miass, Вы писали:
_>Сто раз обсуждали ведь уже. Цикл крутится -> процессор занят. Самое простое в данном случае на мой взгляд — вызывать всё время Sleep(1). Загрузка проца сразу упадёт.
А>Почему поток лезет грязными руками к полям VCL-объектов? А>VCL НЕ ЯВЛЯЕТСЯ ПОТОКОБЕЗОПАСНОЙ БИБЛИОТЕКОЙ А>Единственное, что должен делать тут поток — это PostMessage(Form1.Handle, ...); А>В сообщении нужно передавать через WParam/LParam все необходимые данные (или ссылку на объект, если места не хватает) А>А уже на форме обработчик этого события в контексте визуального потока (а не нашего TMyThread) успешно поменяет Caption.
Не надо сбивать человека с толку. В Synhronize это уже сделано за нас.
А>Далее. Вместо цикла с ProcessMessage делай WaitForSingleObject или любую другую Wait-функцию. Поставь таймаут 500 мс, этого должно хватить. Ждать лучше экземпляр TEvent, так проще всего. WaitForSingleObject выстрелит сама по истечении таймаута или по команде TEvent.SetEvent А>Ресурсы процессора это нагружает минимально.
Так может оно и правильней, но со Sleep проще.
Здравствуйте, Аноним, Вы писали:
А>VCL НЕ ЯВЛЯЕТСЯ ПОТОКОБЕЗОПАСНОЙ БИБЛИОТЕКОЙ
я в курсе , в мануале это написано
это — просто пример ,
кроме того для лабеля так делать можно
безо всяуих вываливаний с хитроподвисами
проверено экспериментально,
п про евенты я тоже прочитал,-> ето идологически верный подход,
но имхо sleep-мой выбор