Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.04.12;
Скачать: CL | DM;

Вниз

Запустить 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;
Скачать: CL | DM;

Наверх




Память: 0.65 MB
Время: 0.011 c
2-1234350269
dmitry1208197320
2009-02-11 14:04
2009.04.12
Как сделать в компоненте TTreeView элемент списка выделенным


15-1233936450
XentaAbsenta
2009-02-06 19:07
2009.04.12
А у меня есть замечательная до идиотизма идея


15-1234733402
Юрий
2009-02-16 00:30
2009.04.12
С днем рождения ! 16 февраля 2009 понедельник


2-1235554500
Scot Storch
2009-02-25 12:35
2009.04.12
Сохранить результа запроса в список


2-1235045880
charoey_mag
2009-02-19 15:18
2009.04.12
Права доступа