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

Вниз

Как нужно делать многопоточные приложения   Найти похожие ветки 

 
ThreadMaster   (2013-03-27 21:59) [0]


procedure TMyThread.Execute;
begin
  while not Terminated do Synchronize(DoWork);
end;

procedure TMyThread.DoWork;
begin
  {Здесь можно уже выполнять те задачи, которые должны быть исполнены процессом}
end;

Статья - Первые шаги с TThread в Delphi - угадайте! откуда ?


 
Ega23 ©   (2013-03-27 22:04) [1]

Архангельский, чё тут гадать-то.


 
Rouse_ ©   (2013-03-27 22:36) [2]

Нет, это "Карих Николай. (Nitro)".
А вот у Архангельского пример с Synchronize был показан как неудачное применение работы с нитью, его просто цитируют через одно место мол он советует так делать :)


 
Ega23 ©   (2013-03-27 22:37) [3]


> А вот у Архангельского пример с Synchronize был показан
> как неудачное применение работы с нитью, его просто цитируют
> через одно место мол он советует так делать :)


Так-то оно так, вот только пример был КРАЙНЕ неудачный, согласись.


 
Rouse_ ©   (2013-03-27 22:39) [4]


> Ega23 ©   (27.03.13 22:37) [3]
> Так-то оно так, вот только пример был КРАЙНЕ неудачный,
> согласись.

С чем согласись? С тем, что он неудачно демонстрирует как нельзя юзать нити?


 
Rouse_ ©   (2013-03-27 22:54) [5]

На всякий случай процитирую для тех кто любит читать между строк:

В процедуре Execute можно непосредственно писать операторы выполнения, вызовы каких-то функций и т.п. Однако, если процедура должна вызывать какие-то методы компонентов VCL или обращаться к свойствам формы, то необходимо соблюдать осторожность, поскольку при этом не исключены конфликты между паралельно выполняемыми нитями. В этом случае в процедуре надо вызывать метод Synchronize, как сказано в комментарии, который вы могли видеть в приведенной выше заготовке модуля.
(c) А.Я. Архангельский


И вот этот выше приведенный кусок с синхронизацией процедуры DoWork все читающие и не любящие думать люди привыкли цитировать :)
Голову то конечно зачем включать - мыж читатели...


 
Ega23 ©   (2013-03-27 23:05) [6]

Саня, всего-то надо было пример чуть-чуть подправить:

procedure TMyThread.Execute;
begin
  while not Terminated do
   DoWork;
end;

procedure TMyThread.DoWork;
begin
 .....
 if SomeCondition then
   Synchronize(SyncProc);
end;

procedure SyncProc;
begin
 /////
end;


А у Архангельского, считай, всё тело Execute через Synchronize выполняется.
Так что, ИМХО, пример весьма неудачный.


 
Rouse_ ©   (2013-03-27 23:11) [7]


> Ega23 ©   (27.03.13 23:05) [6]

Коллега!!! :)))
Ты сей букварь то хоть читал? :)))


 
Ega23 ©   (2013-03-27 23:16) [8]


> Ты сей букварь то хоть читал? :)))

Архангельского? В Дубне где-то валяться должен. Читал очень давно. На память помню, что он не DoWork метод в том примере называл, а просто Work.


 
Игорь Шевченко ©   (2013-03-27 23:17) [9]

Таким образом, при работе с компонентами VCL надежнее строить выполнение следующим образом. Вы пишете процедуру, выполняющую необходимые действия с компонентами VCL/ Пусть вы дали ей имя Work. Тогда вы включаете ее объявление в класс нити, например, в раздел private даете в разделе implementation ее описание, а процедура Execute в этом случае может, например, состоять из единственного оператора Synchronize(Work):

interface
uses
 Classes, ....;

type
 T = class(TThread)
 private
    procedure Work;
 protected
    procedure Execute; override;
 end;
...
implementation
...
procedure T.Work;
begin
...
end;

procedure T.Execute;
begin
 Synchronize(Work);
end;


А. Я. Архангельский, Программирование в Delphi 6, издательство "Бином", 2001


 
Rouse_ ©   (2013-03-27 23:17) [10]


> Ega23 ©   (27.03.13 23:16) [8]

О как, ну что-ж, завтра проверим.
ЗЫ: какой коньяк я люблю, ты помнишь - если что :)))


 
Rouse_ ©   (2013-03-27 23:19) [11]


> Игорь Шевченко ©   (27.03.13 23:17) [9]

Ну как я и говорил - кусок вырванный из контекста :)


 
Игорь Шевченко ©   (2013-03-27 23:23) [12]

Rouse_ ©   (27.03.13 23:19) [11]

Страница 481. Из какого контекста я выдрал ?


 
Rouse_ ©   (2013-03-27 23:29) [13]


> Игорь Шевченко ©   (27.03.13 23:23) [12]

А ты пропустил маленькую малость перед "Таким образом,"

В функции Execute можно непосредственно писать операторы выполнения,вызовы каких-то иных функций и т.п. Однако если функция должна вызывать ка-кие-то методы компонентов VCL или обращаться к свойствам формы, то необходи-мо соблюдать осторожность, поскольку при этом не исключены конфликты между параллельно выполняемыми нитями. В этом случае в функции надо вызывать метод Synchronize, как сказано в комментарии, который вы могли видеть в приведенной выше заготовке модуля.

Метод определен следующим образом:
typedef void fastcall ( closure *TThreadMethod)(void);
void fastcall Synchronize(TThreadMethod SMethod);

В этом определении Method — функция, работающая с компонентами VCL.


Таким образом, при работе с компонентами VCL


 
Rouse_ ©   (2013-03-27 23:30) [14]

В принципе достаточно вот этого:


> В этом определении Method — функция, работающая с компонентами
> VCL.


 
Ega23 ©   (2013-03-27 23:35) [15]


> О как, ну что-ж, завтра проверим.

А чо проверять-то, у меня Архангельский вообще к D5, стопудово то же самое.

Так что именно этот конкретный пример он сделал крайне неудачно. Особенно в книге, рассчитанной на начинающих.
И если бы он его чуть-чуть переписал, то не было бы стОльких веток "у меня поток морозит главную форму, что я делаю не так". А то и делает, что лезет в Архангельского и видит фразу

>процедура Execute в этом случае может, например, состоять
> из единственного оператора Synchronize(Work)


 
Rouse_ ©   (2013-03-27 23:37) [16]


> Ega23 ©   (27.03.13 23:35) [15]

Ну о чем я и говорю - читателям мозг включать не нужно...


 
Ega23 ©   (2013-03-27 23:47) [17]


> Ну о чем я и говорю - читателям мозг включать не нужно..


Сань, да не будет читатель Архангельского (а Архангельский, по-сути, перевод хелпа) включать мозг. Он в первую очередь глянет на пример кода и станет делать также.


 
Rouse_ ©   (2013-03-27 23:49) [18]

Леж, да мне в принципе все равно, просто смешно от этого позитива создаваемого ТС - мол: "Угадайте-кто"?
Ответ-то простой - неучи, либо читатели поперек строк.


 
Rouse_ ©   (2013-03-27 23:58) [19]


> Ega23 ©   (27.03.13 23:05) [6]

Кстати если брать твой вариант, единственно что сделал Архангельский не правильно, так это не написал код вот так:

procedure T.Execute;
begin
// TODO...
Synchronize(Work);
// TODO...
end;


Этого за глаза, без всяких твоих условий :)


 
ThreadMaster   (2013-03-27 23:59) [20]


> Rouse_ ©   (27.03.13 23:49) [18]
> ...просто смешно от этого позитива создаваемого ТС - мол: "Угадайте-кто"?

Эээээ нееее !
ТС спрашивал совсем не "Угадайте-кто" - а "угадайте! откуда ?"

И ответ на этот вопрос дает Яндекс и Гуугл первой ссылкой...

А вот теперь второй вопрос - зачем оно там ?
;)


 
Rouse_ ©   (2013-03-28 00:01) [21]


> ThreadMaster   (27.03.13 23:59) [20]
> А вот теперь второй вопрос - зачем оно там ?

Кто "оно" и где "там"? :))


 
Rouse_ ©   (2013-03-28 00:03) [22]

Или ты про вот эту вот первую ссылку? http://www.delphimaster.ru/articles/thread/

Если да - то я уже ответил, это "Карих Николай. (Nitro)".


 
Игорь Шевченко ©   (2013-03-28 00:05) [23]

Rouse_ ©   (27.03.13 23:29) [13]

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

Ты зря его так защищаешь.


 
Ega23 ©   (2013-03-28 00:06) [24]


> Этого за глаза, без всяких твоих условий :)


Ну или так.


 
Rouse_ ©   (2013-03-28 00:09) [25]


> Игорь Шевченко ©   (28.03.13 00:05) [23]
> Если я читаю книгу и мне нужно включать мозг, для того,
> чтобы понять

Эммм... Игорь, извини, но ты же не Дарью Донцову читаешь :)
Рихтера и Шрайбера тоже на автопилоте осиливал? ;)


 
Игорь Шевченко ©   (2013-03-28 00:10) [26]

Rouse_ ©   (28.03.13 00:09) [25]

А причем тут я ? Я не про себя. Не на автопилоте я осиливал совершенно другие книжки и в совершенно другое время


 
Rouse_ ©   (2013-03-28 00:12) [27]


> Игорь Шевченко ©   (28.03.13 00:05) [23]
> Ты зря его так защищаешь.

И да, я не защищаю - я просто указываю на (IMHO ) ошибочные суждения, сделанные на неверном цитировании материала.
Он для меня не авторитет :)


 
Игорь Шевченко ©   (2013-03-28 00:14) [28]

Rouse_ ©   (28.03.13 00:12) [27]

Я сильно извиняюсь, но цитирование абсолютно верное - весь метод Execute состоит из одного вызова Synchronize, таким образом использование потока здесь не дает ровно никакого выигрыша, кроме усложнения кода и написания лишних слов.


 
Rouse_ ©   (2013-03-28 00:17) [29]

Абсюлютно верно - но в данном случае код верен, т.к. автор приводит пример работы с VCL из сторонней нити, не упоминая о возможной дополнительной полезной нагрузке. Но на то он и пример.


 
Игорь Шевченко ©   (2013-03-28 00:20) [30]

Rouse_ ©   (28.03.13 00:17) [29]

"процедура Execute в этом случае может, например, состоять из единственного оператора Synchronize(Work)"

мало того, что написано словами, так еще и написано в коде. А теперь, внимание, вопрос - с какой целью может потребоваться такой поток, пусть даже при работе с VCL ?


> Но на то он и пример.


Как не надо писать книги по Delphi. Это уже многие поняли.


 
Ega23 ©   (2013-03-28 00:20) [31]


>  но в данном случае код верен

Код - верен. Пример - хреновый.
Вот, собсно, и всё.


 
sniknik ©   (2013-03-28 01:08) [32]

блин, вы хоть версии книг сравните... как будто о разных разговор.

p.s. насколько помню читал вариант с написанным "можно делать так" и + цитируемый код. вариант Rouse_ похоже исправленный... причем похоже евреем исправлено...


 
Германн ©   (2013-03-28 01:40) [33]

Саш, позволь и мне добавить свои три копейки.

> Rouse_ ©   (27.03.13 22:54) [5]
>
> На всякий случай процитирую для тех кто любит читать между
> строк:
>
> 1
> 2
>  
> В процедуре Execute можно непосредственно писать операторы
> выполнения, вызовы каких-то функций и т.п. Однако, если
> процедура должна вызывать какие-то методы компонентов VCL
> или обращаться к свойствам формы, то необходимо соблюдать
> осторожность, поскольку при этом не исключены конфликты
> между паралельно выполняемыми нитями. В этом случае в процедуре
> надо вызывать метод Synchronize, как сказано в комментарии,
>  который вы могли видеть в приведенной выше заготовке модуля.
>

Как тут можно понять автора, кроме как так, что при работе с VCL нужно обязательно использовать метод Synchroniz? А дальше показан пример из которого следует, что в сей метод можно/нужно (думай сам) впихивать весь функционал потока.


 
Германн ©   (2013-03-28 01:48) [34]


> sniknik ©   (28.03.13 01:08) [32]
>
> блин, вы хоть версии книг сравните... как будто о разных
> разговор.

Помня широко известную в узких кругах статью Игоря на королевстве, я сильно сомневаюсь, что есть какая-то существенная разница. :)


 
Григорьев Антон ©   (2013-03-28 08:35) [35]


> Rouse_ ©   (27.03.13 23:19) [11]
> Ну как я и говорил - кусок вырванный из контекста :)

Саша, присоединяюсь к твоим оппонентам. Фраза "процедура Execute в этом случае может, например, состоять из единственного оператора Synchronize(Work)" не может быть правильной ни в каком контексте.


 
Rouse_ ©   (2013-03-28 10:20) [36]


> Игорь Шевченко ©   (28.03.13 00:20) [30]
>
> "процедура Execute в этом случае может, например, состоять
> из единственного оператора Synchronize(Work)"
>
> мало того, что написано словами, так еще и написано в коде.
>  А теперь, внимание, вопрос - с какой целью может потребоваться
> такой поток, пусть даже при работе с VCL ?


Написано правильно. Не должен, а может. Разницу чуствуешь? :)
С какой целью - тоже очень просто, например просто передать ID нити одному из контролов, где она будет использоваться для каких-то своих целей.


> Германн ©   (28.03.13 01:48) [34]
>
> Помня широко известную в узких кругах статью Игоря на королевстве,
>  я сильно сомневаюсь, что есть какая-то существенная разница.
>  :)

В одном из первых выпусков журнала Программист была опубликована статья с названием как-то "17 ошибок Джеффри Рихтера", описывающая технические ошибки в его книге "Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows."

Занимательное и грамотное чтиво, по логике ее можно найти в инете.
Предлагаю интересующимся найти ее, прочесть, написать статью "Почему я не люблю Рихтера" и начать компанию антипиара Рихрера на форумах, мол не нужно читать книги с нелепой кучей ошибок.
Так-то оно наверное правильней будет, зачем избирательно-то писать :)


 
Игорь Шевченко ©   (2013-03-28 10:28) [37]

Rouse_ ©   (28.03.13 10:20) [36]

Ты зря его так защищаешь


 
Ega23 ©   (2013-03-28 10:30) [38]

Только Флёнов, только хардкор!


 
sniknik ©   (2013-03-28 10:30) [39]

Архангельский А.Я. - Программирование в Delphi для Windows. Версии 2006, 2007, Turbo Delphi.
http://saveimg.ru/show-image.php?id=ba9109d524baa103f9c71b2201f49384

все однозначно, типа "в этом случае можно делать так"... как поймет любой (не ищущий подвохов) изучающий материал - "используешь VCL? делай так - ... и пример".

> И вот этот выше приведенный кусок с синхронизацией процедуры DoWork все читающие и не любящие думать люди привыкли цитировать :)
Голову то конечно зачем включать - мыж читатели...
не выше а ниже, с твоей цитаты (последней части) начинается описание, и страница, а пример "как надо" ниже, см. скан.
а выше располагается пример именованного потока с пустым ехекюте (задание имени не в счет).
надо ли объяснять как воспримет неискушенный (только изучающий, а не уже знающий) материал? вот пример именованного, а вот с использованием VCL...


 
sniknik ©   (2013-03-28 10:32) [40]

> Написано правильно. Не должен, а может. Разницу чуствуешь? :)
не может, а не может например ... разницу чувствуешь? :)



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

Текущий архив: 2013.09.01;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.008 c
2-1355836063
oam333
2012-12-18 17:07
2013.09.01
Как через TMemoryStream и IdTCPServer передать переменную Record


10-1184751280
NoXXX
2007-07-18 13:34
2013.09.01
Array[0..7] Of Byte в Activex компонент, Как передать?


15-1364502944
Разведка
2013-03-29 00:35
2013.09.01
Verba - что это?


15-1364430073
RGV
2013-03-28 04:21
2013.09.01
код Делфи to Java


15-1363267161
brother
2013-03-14 17:19
2013.09.01
У кого Win7x64