Форум: "Начинающим";
Текущий архив: 2009.04.12;
Скачать: [xml.tar.bz2];
ВнизЗапустить TThread повторно? Найти похожие ветки
← →
Тын-Дын © (2009-02-22 01:26) [40]
> какая разница?
>зациклить execute и будет тоже самое.
Что значит - какая разница?
Покажи, как зациклишь.
Этот код в принципе не рабочий.
Ты рабочий код приведи.
← →
Тын-Дын © (2009-02-22 01:27) [41]
> никаких евентов здесь не надо.
Не надо так не надо.
Без эвентов покажи.
← →
Медвежонок Пятачок © (2009-02-22 01:39) [42]procedure TBearPigletThread.Execute;
var i : integer; NeedRun : boolean;
begin
while not Terminated do
begin
if fNeedRun then
for i := 1 to 10 do
begin
PostMessage(fHandle,WM_TEST,0,i);
Sleep(300);
end;
else
Sleep(300);
i := SendMessage(fHandle,WM_TEST,1,0);
if i := 0 then Break else fNeedRun := i = 1;
end;
end;
← →
Тын-Дын © (2009-02-22 01:45) [43]
> Медвежонок Пятачок © (22.02.09 01:39) [42]
В твоём коде единственное, что делаеся - выполняется всё время один и тот же цикл. Причём непрерывно.
Если ты смотрел код в [4], то мог заметить, что в нём:
1. Поток после выполнения задания останавливается и ждёт появления новой задачи.
2. Для выполнения можно передавать разные функции - без пересоздания потока.
← →
Тын-Дын © (2009-02-22 01:46) [44]+ обрати внимание на задачу из топика.
← →
Медвежонок Пятачок © (2009-02-22 01:47) [45]и чего?
предлагаешь экономить на Create в то время как считаешь crc у дюжины файлов фик знает какого размера и надеешься дофига выиграть?
← →
Тын-Дын © (2009-02-22 01:48) [46]+вопрос
А почему ты думаешь, что обмен может быть только с потоками, в которых окна есть?
← →
Тын-Дын © (2009-02-22 01:51) [47]
> Медвежонок Пятачок © (22.02.09 01:47) [45]
> и чего?предлагаешь экономить на Create в то время как считаешь
> crc у дюжины файлов фик знает какого размера и надеешься
> дофига выиграть?
Это типичная задача для пула потоков.
1. Если считать CRC у пары миллионов мелких файлов на диске, тем более, если это сетевой диск, выигрыш в скорости будет в десятки раз.
2. Про дюжину файлов можно говорить, если они находятся на дискете, что несколько неудобно.
← →
Тын-Дын © (2009-02-22 01:52) [48]
> предлагаешь экономить на Create
Экономия не на Create, а на CreateThread.
← →
Медвежонок Пятачок © (2009-02-22 01:56) [49]А почему ты думаешь, что обмен может быть только с потоками, в которых окна есть?
если это консоль, то мне вообще странно применение нитки
отработала обработка и readln
Да/Нет/Не знаю
← →
Тын-Дын © (2009-02-22 02:03) [50]
> если это консоль, то мне вообще странно применение нитки
А что тут странного?
Потоки работают в любом прложении.
> отработала обработка и readlnДа/Нет/Не знаю
Непонятно, однако.
Всё-таки хотелось бы видеть код, который реализует эти простейшие функции - выполнение процедуры в отдельном потоке, ожидание, передача новой процедуры для выполнения, корректное завершение.
← →
Медвежонок Пятачок © (2009-02-22 02:05) [51]я же показал уже
← →
Медвежонок Пятачок © (2009-02-22 02:09) [52]в обработчике формы либо выводим мессадждиалог и по нему присваиваем Msg.Result, либо по флагу, который взводится кнопкой.
и все крутится вертится.
но это для извращенцев. как и вариант с ожиданием евента.
когда считаешь црц файлов, на нитке не наэкономишь все равно.
← →
Тын-Дын © (2009-02-22 02:09) [53]
> Медвежонок Пятачок © (22.02.09 02:05) [51]
> я же показал уже
Ты показал только стандартный цикл в методе Execute и обмен с оконной процедурой. Не более того.
← →
Медвежонок Пятачок © (2009-02-22 02:10) [54]Ты показал только стандартный цикл в методе Execute и обмен с оконной процедурой. Не более того.
С ожиданием евента цикл будет нестандартный а волшебный?
← →
Тын-Дын © (2009-02-22 02:17) [55]
> Медвежонок Пятачок © (22.02.09 02:10) [54]
> Ты показал только стандартный цикл в методе Execute и обмен
> с оконной процедурой. Не более того.С ожиданием евента цикл
> будет нестандартный а волшебный?
Код в [4] выполняет задачу.
Твой - нет.
Вот потому тот код и волшебный.
← →
Медвежонок Пятачок © (2009-02-22 02:26) [56]не менее волшебный и без циклов и без евентов
procedure TBearPigletThread.Execute;
var i : integer;
begin
while not Terminated do
begin
for i := 1 to 10 do //Полезная работа
begin
PostMessage(fHandle,WM_TEST,0,i);
Sleep(300);
end;
if SendMessage(fHandle,WM_TEST,1,0) = 0 then Suspend;
end;
end;
procedure TForm1.OnMsg(var AMsg: TMessage);
begin
case AMsg.WParam of
0 : ListBox1.Items.Add(IntToStr(AMsg.LParam));
1 : begin
Button1.Enabled := True;
AMsg.Result := 0;
end;
end;
end;
var t : TThread = nil;
procedure TForm1.Button1Click(Sender: TObject);
begin
if t = nil then t:= TBearPigletThread.CreateIt(Handle) else t.Resume;
Button1.Enabled := False;
end;
← →
Тын-Дын © (2009-02-22 02:30) [57]Сразу маленькая такая ошибка:
> procedure TForm1.Button1Click(Sender: TObject);begin if
> t = nil then t:= TBearPigletThread.CreateIt(Handle) else
> t.Resume; Button1.Enabled := False;end;
Здесь вот этот код -if t = nil then t:= TBearPigletThread.CreateIt(Handle) else t.Resume;
, а именноt.Resume
сработает только в том случае, если поток уже "спит".
Это ведь неправильно? Не так ли?
← →
Тын-Дын © (2009-02-22 02:32) [58]Кроме того, выполняется всё один и тот же цикл в поточной функции.
Это ведь тоже неправильно?
← →
Медвежонок Пятачок © (2009-02-22 02:33) [59]ну да. именно так и хотел автор
хотя можно сделать как хочется. и без всяких евентов.
← →
Тын-Дын © (2009-02-22 02:34) [60]При этом кто сказал, что поток сразу же должен выполнять некую полезную работу?
Он должен дождаться, когда ему передадут процедуру для выполнения и скомандуют об этом.
← →
Медвежонок Пятачок © (2009-02-22 02:35) [61]Кроме того, выполняется всё один и тот же цикл в поточной функции.
ну что за детсад? я могу запустить хоть тысячу разных алгоритмов с каждым новым нажатием кнопки. приведен просто пример нитки с подобием полезной работы
← →
Тын-Дын © (2009-02-22 02:36) [62]
> Медвежонок Пятачок © (22.02.09 02:33) [59]
> ну да. именно так и хотел автор
Неправда.
Автор хотел нечто другое.
Дословно:
> можно ли после окончания исполнения потока повторно использовать
> объект TThread ?
Повторное использование в данном случае - выполнение уже созданным потоком некоторой работы без создания нового потока.
← →
Тын-Дын © (2009-02-22 02:37) [63]
> Медвежонок Пятачок © (22.02.09 02:35) [61]
> Кроме того, выполняется всё один и тот же цикл в поточной
> функции.ну что за детсад? я могу запустить хоть тысячу разных
> алгоритмов с каждым новым нажатием кнопки. приведен просто
> пример нитки с подобием полезной работы<
Вот не надо "некоего подобия".
Приведи рабочий, код, а не выжимки из него, который будет выполнять нужные задачи.
← →
Медвежонок Пятачок © (2009-02-22 02:38) [64]При этом кто сказал, что поток сразу же должен выполнять некую полезную работу?
Он должен дождаться, когда ему передадут процедуру для выполнения и скомандуют об этом.
ну передам я ему под кнопкой пойнтер с кучей полей в которых данные и указатели на мильон разных процедур и тыщщу колбаков и разбужу.
и все будет замечательно вертеться крутиться без евентов-моментов
← →
Тын-Дын © (2009-02-22 02:39) [65]Трындеть я тоже могу сколько угодно.
В коде в начале ветки не зря используются те же эвенты.
И приведён полный рабочий код.
И его немного.
← →
Тын-Дын © (2009-02-22 02:40) [66]
> ну передам я ему под кнопкой пойнтер с кучей полей в которых
> данные и указатели на мильон разных процедур и тыщщу колбаков
> и разбужу.
Ну так передай. Покажи класс.
← →
Медвежонок Пятачок © (2009-02-22 02:40) [67]у меня преподавательский зуд много лет как прошел.
← →
Медвежонок Пятачок © (2009-02-22 02:41) [68]Трындеть я тоже могу сколько угодно.
продолжай трындеть.
а евенты здесь нахрен не нужны.
и я это показал.
← →
Медвежонок Пятачок © (2009-02-22 02:44) [69]Неправда.
Автор хотел нечто другое.
Дословно:
> можно ли после окончания исполнения потока повторно использовать
> объект TThread ?
Повторное использование в данном случае - выполнение уже созданным потоком некоторой работы без создания нового потока.
у меня один поток в одном экземпляре после первого прогона повторно выполняет некторую работу по клику без создания нового потока.
и без дурацких евентов.
← →
Медвежонок Пятачок © (2009-02-22 02:44) [70]а еще и код в три раза компактнее дурацкого примера с евентами
← →
Тын-Дын © (2009-02-22 02:45) [71]
> Медвежонок Пятачок © (22.02.09 02:41) [68]
> Трындеть я тоже могу сколько угодно.продолжай трындеть.а
> евенты здесь нахрен не нужны.и я это показал.
Нет, не показал. Только потрындел.
Код показан в [4].
Приведи класс полностью. Тогда можно будет говорить - показал или нет.
А сейчас - только разговор неконкретный.
← →
Тын-Дын © (2009-02-22 02:46) [72]
> у меня один поток в одном экземпляре после первого прогона
> повторно выполняет некторую работу по клику без создания
> нового потока.
У тебя он выполняет не некую работу.
У тебя он выполняет всё тот же дурацкий цикл.
← →
Медвежонок Пятачок © (2009-02-22 02:46) [73]ну что тебе показать?
пиши. ради праздника покажу.
← →
Тын-Дын © (2009-02-22 02:48) [74]
> Медвежонок Пятачок © (22.02.09 02:46) [73]
> ну что тебе показать?пиши. ради праздника покажу.
Я тебе уже написал.
Теперь дело за тобой - код в студию. Реализованный класс. Где так мало кода, где нет дурацких эвентов...
← →
Тын-Дын © (2009-02-22 02:50) [75]Кстати, и с эвентами, и без эвентов реализуется задача тривиально.
Но без эвентов мне твой код хочется увидеть, коль ты уж так здесь много понаписал против них.
← →
Медвежонок Пятачок © (2009-02-22 03:31) [76]Сначала нитка:
const WM_TEST = WM_USER + 1000;
type
TBearPigletFunc = function(AData : Pointer) : integer;
PBearPigletData = ^TBearPigletData;
TBearPigletData = record
bpd_func : TBearPigletFunc;
bpd_data : Pointer;
bpd_Handle : THandle;
end;
TBearPigletThread = class(TThread)
private
{ Private declarations }
fData : PBearPigletData;
protected
procedure Execute; override;
public
constructor CreateIt(AData : PBearPigletData);
procedure SetData(AData : PBearPigletData);
end;
implementation
constructor TBearPigletThread.CreateIt(AData : PBearPigletData);
begin
inherited Create(True);
fData := AData;
FreeOnTerminate := False;
Resume;
end;
procedure TBearPigletThread.Execute;
begin
while not Terminated do
begin
SendMessage(fData^.bpd_Handle,WM_TEST,0,fData^.bpd_func(fData^.bpd_data));
Dispose(PBearPigletData(fData));
Suspend;
end;
end;
procedure TBearPigletThread.SetData(AData: PBearPigletData);
begin
fData := AData;
end;
← →
Медвежонок Пятачок © (2009-02-22 03:33) [77]Теперь юзающий нитку модуль:
procedure TForm1.OnMsg(var AMsg: TMessage);
begin
case AMsg.WParam of
0 : begin
ListBox1.Items.Add("result of work : " + IntToStr(AMsg.LParam));
Button1.Enabled := True;
Button2.Enabled := True;
AMsg.Result := 0;
end;
end;
end;
var t : TBearPigletThread = nil;
function SomeWork1(AData : Pointer) : integer;
var D:PChar;
begin
D := "C:\*.*";
PostMessage(THandle(AData),LB_DIR,
DDL_DIRECTORY +
DDL_DRIVES +
DDL_EXCLUSIVE +
DDL_HIDDEN +
DDL_READONLY +
DDL_READWRITE +
DDL_SYSTEM,
Integer(D));
Result := 111;
end;
function SomeWork2(AData : Pointer) : integer;
var D:PChar;
begin
D := "D:\*.*";
PostMessage(THandle(AData),LB_DIR,
DDL_DIRECTORY +
DDL_DRIVES +
DDL_EXCLUSIVE +
DDL_HIDDEN +
DDL_READONLY +
DDL_READWRITE +
DDL_SYSTEM,
Integer(D));
Result := 333;
end;
//Просим нитку сделать одно дело
procedure TForm1.Button1Click(Sender: TObject);
var aData : PBearPigletData;
begin
Button1.Enabled := False;
New(aData);
aData^.bpd_func := SomeWork1;
aData^.bpd_data := Pointer(ListBox1.Handle);
aData^.bpd_Handle := Handle;
if t = nil then
t := TBearPigletThread.CreateIt(aData)
else
begin
t.SetData(aData);
t.Resume;
end;
end;
//Просим нитку сделать другое дело
procedure TForm1.Button2Click(Sender: TObject);
var aData : PBearPigletData;
begin
Button2.Enabled := False;
New(aData);
aData^.bpd_func := SomeWork2;
aData^.bpd_data := Pointer(ListBox1.Handle);
aData^.bpd_Handle := Handle;
if t = nil then
t := TBearPigletThread.CreateIt(aData)
else
begin
t.SetData(aData);
t.Resume;
end;
end;
← →
Cobalt © (2009-02-22 03:46) [78]Блин, я уже потерялся в ваших обсуждениях :)
Поясню, что же я хотел.
А хотел я собственно немногого - использовать именно класс TThread, а не сам поток, поскольку создание потока в моем случае - ничтожнейшая часть всей его работы.
Типа как (условно-сокращенно):
formOnCreate
begin
FThread:=TWorkThread.Create(wkNone);
end;
btnUpdateFullOnClick:
begin
FThread.Run(wkUpdateFull);
UpdateButtonsState;
end;
btnUpdatePartOnClick:
begin
FThread.Run(wkUpdatePart);
UpdateButtonsState;
end;
UpdateButtonsState;
begin
for i:=0 to ActionsCount-1 do
Actions[i].Enabled:=not FThread.IsRunning;
begin
А в методе FThread.Run(wkUpdatePart);:и т.п.
CreateThread()
Т.е. дернул объект - тот запустил поток, обновил состояния, типа Terminated, Suspended и т.п.
← →
Медвежонок Пятачок © (2009-02-22 03:49) [79]и что это меняет? в чем суть пробемы-то?
← →
Тын-Дын © (2009-02-22 03:50) [80]Ну вобщем-то всё нормально.
За исключением таких моментов:
1. Нет проверки на то, что поток занят выполнением. Отключение кнопок - это несерьёзно.
2. Код не защищён от одновременной попытки запуска нового задания.
Это приведёт к сложноуловимым ошибкам при выполнении в многопоточном приложении. Особенно на многопроцессорном компьютере.
Над этими проблемами ещё придётся поработать тому, кто возьмётся писать таким образом-)
Страницы: 1 2 3 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.04.12;
Скачать: [xml.tar.bz2];
Память: 0.63 MB
Время: 0.008 c