Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
15-1234440948
Michael
2009-02-12 15:15
2009.04.12
Алгоритм декодирования JPEG


2-1235069146
vps
2009-02-19 21:45
2009.04.12
Out of memory,


4-1208106519
yus
2008-04-13 21:08
2009.04.12
TWAIN_32.DLL


15-1234474201
Юрий
2009-02-13 00:30
2009.04.12
С днем рождения ! 13 февраля 2009 пятница


15-1234630411
Маэстро
2009-02-14 19:53
2009.04.12
Ламерский вопрос%)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский