Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];

Вниз

Непонятка с TThread.   Найти похожие ветки 

 
NumLock ©   (2004-04-21 17:11) [0]

Здравствуйте мастера.
Вот такая вот непоняточка вышла.
Создавал трэд, как показано в http://www.delphimaster.ru/articles/thread/index.html но в процедуре DoWork у меня длительный цикл, при выполнении которого форма не отвечает на запросы. Это так должно быть, или я что то не так делаю?
Заранее благодарен.
NumLock


 
NumLock ©   (2004-04-21 17:11) [0]

Здравствуйте мастера.
Вот такая вот непоняточка вышла.
Создавал трэд, как показано в http://www.delphimaster.ru/articles/thread/index.html но в процедуре DoWork у меня длительный цикл, при выполнении которого форма не отвечает на запросы. Это так должно быть, или я что то не так делаю?
Заранее благодарен.
NumLock


 
Palladin ©   (2004-04-21 17:15) [1]

Очень хороший пример как писать безсмысленные потоки.
Synchronize + F1


 
Palladin ©   (2004-04-21 17:15) [1]

Очень хороший пример как писать безсмысленные потоки.
Synchronize + F1


 
Romkin ©   (2004-04-21 17:20) [2]

ХМ. Какой идиот написал эту статью?!


 
Romkin ©   (2004-04-21 17:20) [2]

ХМ. Какой идиот написал эту статью?!


 
Тимохов ©   (2004-04-21 17:21) [3]


> Romkin ©   (21.04.04 17:20) [2]

во как - на родном сайте и не такое найдешь.

Автору.
Код приведи, что написал.


 
Тимохов ©   (2004-04-21 17:21) [3]


> Romkin ©   (21.04.04 17:20) [2]

во как - на родном сайте и не такое найдешь.

Автору.
Код приведи, что написал.


 
Digitman ©   (2004-04-21 17:23) [4]


> Какой идиот написал эту статью


У идиота есть конкретные координаты - Карих Николай


 
Digitman ©   (2004-04-21 17:23) [4]


> Какой идиот написал эту статью


У идиота есть конкретные координаты - Карих Николай


 
Тимохов ©   (2004-04-21 17:24) [5]

полагаю не авторе дело, а в том, кто это поместил...


 
Тимохов ©   (2004-04-21 17:24) [5]

полагаю не авторе дело, а в том, кто это поместил...


 
NumLock ©   (2004-04-21 17:25) [6]

Так как же сделать чтоб форма не подвисала при выполнении длительного цикла? Application.ProcessMessage не подходит.


 
NumLock ©   (2004-04-21 17:25) [6]

Так как же сделать чтоб форма не подвисала при выполнении длительного цикла? Application.ProcessMessage не подходит.


 
panov ©   (2004-04-21 17:26) [7]

http://www.delphimaster.ru/articles/panov/index.html


 
panov ©   (2004-04-21 17:26) [7]

http://www.delphimaster.ru/articles/panov/index.html


 
Palladin ©   (2004-04-21 17:26) [8]

Предлагаю всю статью в орешник.


 
Palladin ©   (2004-04-21 17:26) [8]

Предлагаю всю статью в орешник.


 
Тимохов ©   (2004-04-21 17:27) [9]

Автору.
Поток + Synchronize (если надо, что то в форме отображать) чем не подходит?


 
Тимохов ©   (2004-04-21 17:27) [9]

Автору.
Поток + Synchronize (если надо, что то в форме отображать) чем не подходит?


 
panov ©   (2004-04-21 17:28) [10]

Execute.
        В Execute должен выполняться весь код, который должен выполняться «параллельно» основному потоку. Как правило, если поток предназначен для выполнения многократно повторяющегося кода (цикла), то в Execute используется конструкция следующего вида:

while not Terminated do
begin
//    В этом месте выполняется весь необходимый код.
    …
// Если здесь необходимо обновлять некоторые данные в основном потоке,
// то здесь используйте метод Synchronize.
    Synchronize(MyUpdateProcedure);
// Процедуру MyUpdateProcedure определяем в описании нашего класса.
end;

Synchronize
        Так как процедура, вызываемая в методе Synchronize выполняется в основном потоке, то на время выполнения Synchronize главная форма будет блокирована для ввода, обновления информации, как это происходит при длительных операциях в основном потоке.
Поэтому этот метод надо вызывать по возможности реже.


 
panov ©   (2004-04-21 17:28) [10]

Execute.
        В Execute должен выполняться весь код, который должен выполняться «параллельно» основному потоку. Как правило, если поток предназначен для выполнения многократно повторяющегося кода (цикла), то в Execute используется конструкция следующего вида:

while not Terminated do
begin
//    В этом месте выполняется весь необходимый код.
    …
// Если здесь необходимо обновлять некоторые данные в основном потоке,
// то здесь используйте метод Synchronize.
    Synchronize(MyUpdateProcedure);
// Процедуру MyUpdateProcedure определяем в описании нашего класса.
end;

Synchronize
        Так как процедура, вызываемая в методе Synchronize выполняется в основном потоке, то на время выполнения Synchronize главная форма будет блокирована для ввода, обновления информации, как это происходит при длительных операциях в основном потоке.
Поэтому этот метод надо вызывать по возможности реже.


 
Юрий Зотов ©   (2004-04-21 17:31) [11]

> NumLock ©   (21.04.04 17:25) [6]

Уберите Synchronize. Потом, если потребуется, снова добавьте - но только после того, как прочтете в справке, что это такое и для чего оно нужно.


 
Юрий Зотов ©   (2004-04-21 17:31) [11]

> NumLock ©   (21.04.04 17:25) [6]

Уберите Synchronize. Потом, если потребуется, снова добавьте - но только после того, как прочтете в справке, что это такое и для чего оно нужно.


 
Игорь Шевченко ©   (2004-04-21 17:33) [12]

Я свои две копейки вставлю: http://www.schevchenko.net.ru/SRC/SuperMarket_50.zip


 
Игорь Шевченко ©   (2004-04-21 17:33) [12]

Я свои две копейки вставлю: http://www.schevchenko.net.ru/SRC/SuperMarket_50.zip


 
Игорь Шевченко ©   (2004-04-21 17:34) [13]

Palladin ©   (21.04.04 17:26)

А на что заменять ? :) Тогда уж в орешник и Архангельского, целиком, у него в книжках такие примеры.


 
Игорь Шевченко ©   (2004-04-21 17:34) [13]

Palladin ©   (21.04.04 17:26)

А на что заменять ? :) Тогда уж в орешник и Архангельского, целиком, у него в книжках такие примеры.


 
Тимохов ©   (2004-04-21 17:35) [14]

На фотографии мастреров - на них вся надежда

:)


 
Тимохов ©   (2004-04-21 17:35) [14]

На фотографии мастреров - на них вся надежда

:)


 
Romkin ©   (2004-04-21 17:40) [15]

Игорь Шевченко ©  (21.04.04 17:34) [13] Что, серьезно у него так?!! Мдя...
Кстати, ты бы выложил на своем сайте исходники в виде html файлов, а то - скачать архив, распаковать куда-то, и только потом увидишь :(


 
Romkin ©   (2004-04-21 17:40) [15]

Игорь Шевченко ©  (21.04.04 17:34) [13] Что, серьезно у него так?!! Мдя...
Кстати, ты бы выложил на своем сайте исходники в виде html файлов, а то - скачать архив, распаковать куда-то, и только потом увидишь :(


 
Palladin ©   (2004-04-21 17:49) [16]

Видел кусок кода тоже из Архангельского, где он разбирает пример ловушек. Ошибка имеет место быть.

А статью можно в оршеник не всю, а фразу "Поединок" Thread-ов :-)... она мне очень понравилась :) при таком коде...


 
Palladin ©   (2004-04-21 17:49) [16]

Видел кусок кода тоже из Архангельского, где он разбирает пример ловушек. Ошибка имеет место быть.

А статью можно в оршеник не всю, а фразу "Поединок" Thread-ов :-)... она мне очень понравилась :) при таком коде...


 
Digitman ©   (2004-04-21 17:49) [17]

между прочим, Карих слово "шаблон" заключил в кавычки)

ессс-но, для тех кто на бронепоезде, кавычки - излишество в изложении материала, поэтому ШАБЛОН для оных есть прямое руководство к бездумному сдиранию примера


 
Digitman ©   (2004-04-21 17:49) [17]

между прочим, Карих слово "шаблон" заключил в кавычки)

ессс-но, для тех кто на бронепоезде, кавычки - излишество в изложении материала, поэтому ШАБЛОН для оных есть прямое руководство к бездумному сдиранию примера


 
NumLock ©   (2004-04-21 17:52) [18]

У меня так получается, что во время выполнения Execute форма виснет. Смысл тогда трэдов.


 
NumLock ©   (2004-04-21 17:52) [18]

У меня так получается, что во время выполнения Execute форма виснет. Смысл тогда трэдов.


 
Тимохов ©   (2004-04-21 17:54) [19]


> NumLock ©   (21.04.04 17:52) [18]


уже задолбался от вас код просить.
комерческая тайна?
или просто лень нормально готовить вопрос?


 
Тимохов ©   (2004-04-21 17:54) [19]


> NumLock ©   (21.04.04 17:52) [18]


уже задолбался от вас код просить.
комерческая тайна?
или просто лень нормально готовить вопрос?


 
panov ©   (2004-04-21 18:00) [20]

Вот из-за чего, оказывается, постоянно возникают вопросы по использованию Synchronize в потоках...


 
panov ©   (2004-04-21 18:00) [20]

Вот из-за чего, оказывается, постоянно возникают вопросы по использованию Synchronize в потоках...


 
Palladin ©   (2004-04-21 18:03) [21]


> NumLock ©   (21.04.04 17:52) [18]

тебя уже три раза направили на истинный путь, ты читать то умеешь?


 
Palladin ©   (2004-04-21 18:03) [21]


> NumLock ©   (21.04.04 17:52) [18]

тебя уже три раза направили на истинный путь, ты читать то умеешь?


 
Игорь Шевченко ©   (2004-04-21 18:05) [22]

Цитата из статьи "За что я не люблю Архангельского" :

"Примеры с потоками имеют обычно структуру:
procedure T1Thread.Execute;
begin
 repeat
   Syncronize(SomeProc);
 until Terminated;
end;
Теперь понятно, откуда в форумах вопросы про потоки с таким кодом...
"


 
Игорь Шевченко ©   (2004-04-21 18:05) [22]

Цитата из статьи "За что я не люблю Архангельского" :

"Примеры с потоками имеют обычно структуру:
procedure T1Thread.Execute;
begin
 repeat
   Syncronize(SomeProc);
 until Terminated;
end;
Теперь понятно, откуда в форумах вопросы про потоки с таким кодом...
"


 
Digitman ©   (2004-04-21 18:05) [23]


> NumLock ©   (21.04.04 17:52) [18]
> У меня так получается, что во время выполнения Execute форма
> виснет. Смысл тогда трэдов.


виснет не форма.
форма вообще не может "виснуть"

"виснет" осн.код.поток, в контексте которого выполняется то что ты передал параметром в sincgronize()

а это самое "то что ты передал" вполне может быть длительным циклом, в ходе исполнения которого в его алгоритме (тобой реализованным !!) нет ни намека на выборку/обработку оконных сообщений, адресованных окнам, созданным в контексте осн.код.потока.. т.е. осн.код.поток занялся выполнением указанного тобой цикла. в то время как ОСНОВНАЯ его задача - оперативно реагировать на оконные сообщения и сообщения польз. ввода/вывода


 
Digitman ©   (2004-04-21 18:05) [23]


> NumLock ©   (21.04.04 17:52) [18]
> У меня так получается, что во время выполнения Execute форма
> виснет. Смысл тогда трэдов.


виснет не форма.
форма вообще не может "виснуть"

"виснет" осн.код.поток, в контексте которого выполняется то что ты передал параметром в sincgronize()

а это самое "то что ты передал" вполне может быть длительным циклом, в ходе исполнения которого в его алгоритме (тобой реализованным !!) нет ни намека на выборку/обработку оконных сообщений, адресованных окнам, созданным в контексте осн.код.потока.. т.е. осн.код.поток занялся выполнением указанного тобой цикла. в то время как ОСНОВНАЯ его задача - оперативно реагировать на оконные сообщения и сообщения польз. ввода/вывода


 
Тимохов ©   (2004-04-21 18:08) [24]

Во как мастера накинулись на "потоки".
За что люблю форум - это на дурцкий вопрос, но по интеренсной теме столько постов и таких людей - просто закачаешься.
Я бы игнорировал такие вопросы - автору по барабану на ответы. Ему лень даже код привести.


 
Тимохов ©   (2004-04-21 18:08) [24]

Во как мастера накинулись на "потоки".
За что люблю форум - это на дурцкий вопрос, но по интеренсной теме столько постов и таких людей - просто закачаешься.
Я бы игнорировал такие вопросы - автору по барабану на ответы. Ему лень даже код привести.


 
NumLock ©   (2004-04-21 18:12) [25]

> Palladin
Все все, не надо кричать, разберусь. Просто среди Вашей дискусии не заметил ссылку.
Спасибо за информацию.

> Тимохов

.....
type
 TMyThread = class(TThread)
 private
 protected
   procedure Execute; override;
 end;
 TForm1 = class(TForm)
   Progress: TProgress
....
 end;

var Form1: TForm1;
   MyThread:TMyThread;
implementation
{$R *.DFM}
procedure TMyThread.Execute;
begin
  // Тут прорисовываю фрактал
end;
.....
procedure TForm1.PaintDecl(Rect1, Rect2: TRect; var bitmap:TBitMap); // прорисовка фракрала    
begin
   THRect1:=Rect1;
   THRect2:=Rect2;
   MyThread.Execute;
end;
.....
в FormCreate
   MyThread:=TMyThread.Create(true);
   MyThread.FreeOnTerminate:=true;
   MyThread.Priority:=tpNormal;
....
и останавливаю по
   if MyThread.Terminated then MyThread.Terminate;
....
Вроде все, если слишком код глупый, ГРОМКО не смейся, всетаки пол часа с трэдами работаю


 
NumLock ©   (2004-04-21 18:12) [25]

> Palladin
Все все, не надо кричать, разберусь. Просто среди Вашей дискусии не заметил ссылку.
Спасибо за информацию.

> Тимохов

.....
type
 TMyThread = class(TThread)
 private
 protected
   procedure Execute; override;
 end;
 TForm1 = class(TForm)
   Progress: TProgress
....
 end;

var Form1: TForm1;
   MyThread:TMyThread;
implementation
{$R *.DFM}
procedure TMyThread.Execute;
begin
  // Тут прорисовываю фрактал
end;
.....
procedure TForm1.PaintDecl(Rect1, Rect2: TRect; var bitmap:TBitMap); // прорисовка фракрала    
begin
   THRect1:=Rect1;
   THRect2:=Rect2;
   MyThread.Execute;
end;
.....
в FormCreate
   MyThread:=TMyThread.Create(true);
   MyThread.FreeOnTerminate:=true;
   MyThread.Priority:=tpNormal;
....
и останавливаю по
   if MyThread.Terminated then MyThread.Terminate;
....
Вроде все, если слишком код глупый, ГРОМКО не смейся, всетаки пол часа с трэдами работаю


 
NumLock ©   (2004-04-21 18:14) [26]

очепятка --> if not MyThread.Terminated then MyThread.Terminate;


 
NumLock ©   (2004-04-21 18:14) [26]

очепятка --> if not MyThread.Terminated then MyThread.Terminate;


 
Тимохов ©   (2004-04-21 18:16) [27]


> NumLock ©   (21.04.04 18:12) [25]

жуть.
Вы повырезали то, без чего нельзя вообще ничего понять.

1. Где вы поток запускаете.
2. Это вообще какая-то ерунда "MyThread.Terminated then MyThread.Terminate". Так потоки не останавливают. Можно так

MyThread.FreeOnTermiante := False;
MyThread.Termiante;
MyThread.WaitFor;
MyThread.Free;

Но для этого в execute надо переодически отслеживать состояние terminated. Если true, то выходить из execute.

3. Содержание метода execute вы вообще покоцали (самое интереснове).


 
Тимохов ©   (2004-04-21 18:16) [27]


> NumLock ©   (21.04.04 18:12) [25]

жуть.
Вы повырезали то, без чего нельзя вообще ничего понять.

1. Где вы поток запускаете.
2. Это вообще какая-то ерунда "MyThread.Terminated then MyThread.Terminate". Так потоки не останавливают. Можно так

MyThread.FreeOnTermiante := False;
MyThread.Termiante;
MyThread.WaitFor;
MyThread.Free;

Но для этого в execute надо переодически отслеживать состояние terminated. Если true, то выходить из execute.

3. Содержание метода execute вы вообще покоцали (самое интереснове).


 
Digitman ©   (2004-04-21 18:17) [28]


> NumLock ©   (21.04.04 18:12) [25]


слухай сюда ...

если Архангельские и Карихи не помогают, ЛУЧШИМ средством "разборок" при "непонятках" явл-ся исследование исх.кода класса TThread ... он у тебя - прямо перед носом, в модуле classes .. без этого ты долго будешь экспериментировать "вслепую" и задавать "глупые вопросы" ...

вот это

MyThread.Execute;

есть чуть ли не центральная "глупость" в той логике, что ты привел

если это не так - приведи цитату из первоисточника, на основании которого ты написал эту строчку


 
Digitman ©   (2004-04-21 18:17) [28]


> NumLock ©   (21.04.04 18:12) [25]


слухай сюда ...

если Архангельские и Карихи не помогают, ЛУЧШИМ средством "разборок" при "непонятках" явл-ся исследование исх.кода класса TThread ... он у тебя - прямо перед носом, в модуле classes .. без этого ты долго будешь экспериментировать "вслепую" и задавать "глупые вопросы" ...

вот это

MyThread.Execute;

есть чуть ли не центральная "глупость" в той логике, что ты привел

если это не так - приведи цитату из первоисточника, на основании которого ты написал эту строчку


 
Romkin ©   (2004-04-21 18:18) [29]

ЭЭЭ! А вот здесь аккуратнее :)) Просто так рисовать на форме нельзя, надо именно через syncronize :)
Если же ты просто рисуешь в битмапе, а потом, по окончании потока, показываешь этот битмап, то все в порядке


 
Romkin ©   (2004-04-21 18:18) [29]

ЭЭЭ! А вот здесь аккуратнее :)) Просто так рисовать на форме нельзя, надо именно через syncronize :)
Если же ты просто рисуешь в битмапе, а потом, по окончании потока, показываешь этот битмап, то все в порядке


 
Тимохов ©   (2004-04-21 18:18) [30]


> MyThread.Execute;

А это он так поток запускает :))


 
Тимохов ©   (2004-04-21 18:18) [30]


> MyThread.Execute;

А это он так поток запускает :))


 
Digitman ©   (2004-04-21 18:21) [31]


> Тимохов ©   (21.04.04 18:18) [30]


я понимаю ... ибо читать хэлп нынче не модно ... хотя в нем черным по белому написано, что есть данный метод и с чем его едят

Provides an abstract method that contains the code which executes when the thread is run.

Description

Override Execute and insert the code that should be executed when the thread runs. Execute is responsible for checking the value of the Terminated property to determine if the thread needs to exit.

A thread executes when Create is called if CreateSuspended set to False, or when Resume is first called after the thread is created if CreateSuspended set to True.


 
Digitman ©   (2004-04-21 18:21) [31]


> Тимохов ©   (21.04.04 18:18) [30]


я понимаю ... ибо читать хэлп нынче не модно ... хотя в нем черным по белому написано, что есть данный метод и с чем его едят

Provides an abstract method that contains the code which executes when the thread is run.

Description

Override Execute and insert the code that should be executed when the thread runs. Execute is responsible for checking the value of the Terminated property to determine if the thread needs to exit.

A thread executes when Create is called if CreateSuspended set to False, or when Resume is first called after the thread is created if CreateSuspended set to True.


 
Тимохов ©   (2004-04-21 18:22) [32]

Полностью согласен с Digitman - нечего глупые вопросы задавать. Сначала изучать надо, потом задавать конктетные не глупые вопросы.

Начните:
1. Исходники класса TThread
2. Статья http://mbo88.narod.ru/ToC.html - пока не читал, но MBo плохого не переведет.


 
Тимохов ©   (2004-04-21 18:22) [32]

Полностью согласен с Digitman - нечего глупые вопросы задавать. Сначала изучать надо, потом задавать конктетные не глупые вопросы.

Начните:
1. Исходники класса TThread
2. Статья http://mbo88.narod.ru/ToC.html - пока не читал, но MBo плохого не переведет.


 
Digitman ©   (2004-04-21 18:23) [33]

не модно так же публично признаться в элементарном незнании специализированного аглицкого языка ... о разговорном общеупотребительном языке уж и не заикаюсь


 
Digitman ©   (2004-04-21 18:23) [33]

не модно так же публично признаться в элементарном незнании специализированного аглицкого языка ... о разговорном общеупотребительном языке уж и не заикаюсь


 
NumLock ©   (2004-04-21 18:24) [34]

> Тимохов
1. Поток запускаю процедурой
procedure TForm1.PaintDecl(Rect1, Rect2: TRect; var bitmap:TBitMap); // прорисовка фракрала    
begin
  THRect1:=Rect1;
  THRect2:=Rect2;
  MyThread.Execute;
end;
из разных мест в проге, по мере необходимости
2. С остановкой, ладно, пока не в этом дело, зачем останавливать, если форма не отвечает на запросы вообще, а ждет завершения...
3. В execute  цикл по всему PaintBox + для каждой точки еще :
function Mandel1(var a, b: extended): TColor; // описывает мпожество мандельбротта
var x, y, X2, Y2, xy, r:extended;
   k:integer;
begin
   r:=0;
   x:=0;
   y:=0;
   k:=511; // количество итераций, при изменении прийдется изменить и палитру
   while (k>0) and (r<4) do begin
       x2:=x*x;
       y2:=y*y;
       xy:=x*y;
       x:=x2-y2+a;
       y:=2*xy+b;
       r:=x2+y2;
       dec(k);
   end;
   Result:=Palitra(k);
end;


 
NumLock ©   (2004-04-21 18:24) [34]

> Тимохов
1. Поток запускаю процедурой
procedure TForm1.PaintDecl(Rect1, Rect2: TRect; var bitmap:TBitMap); // прорисовка фракрала    
begin
  THRect1:=Rect1;
  THRect2:=Rect2;
  MyThread.Execute;
end;
из разных мест в проге, по мере необходимости
2. С остановкой, ладно, пока не в этом дело, зачем останавливать, если форма не отвечает на запросы вообще, а ждет завершения...
3. В execute  цикл по всему PaintBox + для каждой точки еще :
function Mandel1(var a, b: extended): TColor; // описывает мпожество мандельбротта
var x, y, X2, Y2, xy, r:extended;
   k:integer;
begin
   r:=0;
   x:=0;
   y:=0;
   k:=511; // количество итераций, при изменении прийдется изменить и палитру
   while (k>0) and (r<4) do begin
       x2:=x*x;
       y2:=y*y;
       xy:=x*y;
       x:=x2-y2+a;
       y:=2*xy+b;
       r:=x2+y2;
       dec(k);
   end;
   Result:=Palitra(k);
end;


 
Тимохов ©   (2004-04-21 18:26) [35]


> NumLock ©   (21.04.04 18:24) [34]

очень советую не задавать пока вопросы, а посидеть хотя бы денька два над документацией (выше привел).
потом радостно будем отвечать на ваши нормальные вопросы.


 
Тимохов ©   (2004-04-21 18:26) [35]


> NumLock ©   (21.04.04 18:24) [34]

очень советую не задавать пока вопросы, а посидеть хотя бы денька два над документацией (выше привел).
потом радостно будем отвечать на ваши нормальные вопросы.


 
Digitman ©   (2004-04-21 18:28) [36]


> Поток запускаю процедурой


читай [31] !!

или первоисточник - справка по этой теме в Делфи

там ЧЕРНЫМ ПО БЕЛОМУ написано, в какой момент и каким образом стартует трэд ! далеко ведь не в тот момент, когда ты с какого-то перепугу вызываешь MyThread.Execute

считай , что Execute() - просто некая обычная подпрограмма

а подпрограмма, будучи вызванной, исполняется в том код.потоке, который вызвал эту подпрограмму


 
Digitman ©   (2004-04-21 18:28) [36]


> Поток запускаю процедурой


читай [31] !!

или первоисточник - справка по этой теме в Делфи

там ЧЕРНЫМ ПО БЕЛОМУ написано, в какой момент и каким образом стартует трэд ! далеко ведь не в тот момент, когда ты с какого-то перепугу вызываешь MyThread.Execute

считай , что Execute() - просто некая обычная подпрограмма

а подпрограмма, будучи вызванной, исполняется в том код.потоке, который вызвал эту подпрограмму


 
NumLock ©   (2004-04-21 18:28) [37]

MyThread.Execute;
с этим разобрался, понял что глупость.
Все дальше сам, спасибо за советы


 
NumLock ©   (2004-04-21 18:28) [37]

MyThread.Execute;
с этим разобрался, понял что глупость.
Все дальше сам, спасибо за советы


 
Piter ©   (2004-04-21 22:13) [38]

Народ, тут вроде хотели произвести чистку FAQ"а... может, чистку статей тоже нужно сделать?

Ибо

"Этому вопросу как раз и посвящена данная статья - создание многопоточных приложений (со множеством дочерних процессов, которые выполняются одновременно)."

"зачем же нужен класс Thread и его потомки? Во-первых, этот объект позволяет создавать как бы несколько программ в одной (несколько процессов, или, потоков). "

" В-третьих, из этих процессов можно легко получить доступ ко всем глобальным данным программы, т.к. класс процесса является, по сути, просто частью программы "

Это только из вступления...


 
Piter ©   (2004-04-21 22:13) [38]

Народ, тут вроде хотели произвести чистку FAQ"а... может, чистку статей тоже нужно сделать?

Ибо

"Этому вопросу как раз и посвящена данная статья - создание многопоточных приложений (со множеством дочерних процессов, которые выполняются одновременно)."

"зачем же нужен класс Thread и его потомки? Во-первых, этот объект позволяет создавать как бы несколько программ в одной (несколько процессов, или, потоков). "

" В-третьих, из этих процессов можно легко получить доступ ко всем глобальным данным программы, т.к. класс процесса является, по сути, просто частью программы "

Это только из вступления...


 
Юрий Зотов ©   (2004-04-21 22:41) [39]

> NumLock ©   (21.04.04 18:28) [37]

Напишите Execute по такой схеме, и все будет чудненько.

procedure MyThread.Execute;
begin
 while not Terminated do
 begin
   ... // Что-то вычисляем
   ... // Здесь надо перерисовать форму - см. ниже.
 end
end;

Перерисовку формы нельзя делать непосредственно из второго потока. Можно делать ее через Synchronize, но при этом второй поток на время перерисовки остановится и вычисления могут сильно замедлиться. Чтобы этого избежать, можно вместо прямой перерисовки послать (строго через PostMessage, но ни в коем случае не через SendMessage) форме любое сообщение (например, WM_USER+100) и в его параметрах передать нужные для перерисовки данные. После отправки сообщения второй поток начинает следубщий цикл вычислений, а форма, получив сообщение, перерисовывает все, что ей нужно (например, прогрессбар). В итоге Вы получите и нормальную работу формы, и максимально возможнуюю в данных условиях скорость вычислений.

И еще - не надо перерисовывать слишком часто. Предположим, прогрессбар имеет ширину 250 пикселей и должен отобразить миллион циклов вычислений. Значит, нет никакого смысла перерисовывать его чаще, чем раз в 4 тыс. циклов - иначе время на перерисовку будет потеряно, а визуально ничего не изменится.

Последнее - Execute вызывать не нужно. Сам по себе это никакой не поток, а самый обычный метод. Поэтому в каком потоке он будет вызван - в том он и выполнится. Фокус в том, что код VCL сначала создает поток Windows и уже из него САМ вызывает Execute.

Если Вы создали второй поток с CreateSuspended=False, то все это произойдет автоматически, а если с True, то вызовите Resume - и остальное тоже произойдет автоматически..


 
Юрий Зотов ©   (2004-04-21 22:41) [39]

> NumLock ©   (21.04.04 18:28) [37]

Напишите Execute по такой схеме, и все будет чудненько.

procedure MyThread.Execute;
begin
 while not Terminated do
 begin
   ... // Что-то вычисляем
   ... // Здесь надо перерисовать форму - см. ниже.
 end
end;

Перерисовку формы нельзя делать непосредственно из второго потока. Можно делать ее через Synchronize, но при этом второй поток на время перерисовки остановится и вычисления могут сильно замедлиться. Чтобы этого избежать, можно вместо прямой перерисовки послать (строго через PostMessage, но ни в коем случае не через SendMessage) форме любое сообщение (например, WM_USER+100) и в его параметрах передать нужные для перерисовки данные. После отправки сообщения второй поток начинает следубщий цикл вычислений, а форма, получив сообщение, перерисовывает все, что ей нужно (например, прогрессбар). В итоге Вы получите и нормальную работу формы, и максимально возможнуюю в данных условиях скорость вычислений.

И еще - не надо перерисовывать слишком часто. Предположим, прогрессбар имеет ширину 250 пикселей и должен отобразить миллион циклов вычислений. Значит, нет никакого смысла перерисовывать его чаще, чем раз в 4 тыс. циклов - иначе время на перерисовку будет потеряно, а визуально ничего не изменится.

Последнее - Execute вызывать не нужно. Сам по себе это никакой не поток, а самый обычный метод. Поэтому в каком потоке он будет вызван - в том он и выполнится. Фокус в том, что код VCL сначала создает поток Windows и уже из него САМ вызывает Execute.

Если Вы создали второй поток с CreateSuspended=False, то все это произойдет автоматически, а если с True, то вызовите Resume - и остальное тоже произойдет автоматически..


 
Piter ©   (2004-04-21 23:34) [40]

Кстати, посмотрел тут реализацию TThread.Synchronize и сразу не понял:

я привык ей передавать метод, который надо вызывать из главного потока. Ну это и правильно, работает.

Но в исходниках читаем, ей вот что передается:

TThread.Synchronize(ASyncRec: PSynchronizeRecord)

причем

PSynchronizeRecord = ^TSynchronizeRecord;
 TSynchronizeRecord = record
   FThread: TObject;
   FMethod: TThreadMethod;
   FSynchronizeException: TObject;
 end;

То есть, процедуре Synchronize надо передавать получается указатель на некую структуру! Что за бред? Никогда никакого указателя на структуру не передавал и все работает... чего я не понимаю?


 
Piter ©   (2004-04-21 23:34) [40]

Кстати, посмотрел тут реализацию TThread.Synchronize и сразу не понял:

я привык ей передавать метод, который надо вызывать из главного потока. Ну это и правильно, работает.

Но в исходниках читаем, ей вот что передается:

TThread.Synchronize(ASyncRec: PSynchronizeRecord)

причем

PSynchronizeRecord = ^TSynchronizeRecord;
 TSynchronizeRecord = record
   FThread: TObject;
   FMethod: TThreadMethod;
   FSynchronizeException: TObject;
 end;

То есть, процедуре Synchronize надо передавать получается указатель на некую структуру! Что за бред? Никогда никакого указателя на структуру не передавал и все работает... чего я не понимаю?



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.69 MB
Время: 0.036 c
9-1070054990
mrAld
2003-11-29 00:29
2004.05.09
FPS и потоки


14-1082358913
Ega23
2004-04-19 11:15
2004.05.09
Редактор inf-файлов


7-1079093913
Arm79
2004-03-12 15:18
2004.05.09
Перехват системных комбинаций клавиш для скринсайвера


1-1082462076
msgipss
2004-04-20 15:54
2004.05.09
Для чего нужен TEvent из модуля SyncObjs


6-1079338786
Аноним
2004-03-15 11:19
2004.05.09
TClientSocket, TServerSocket





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский