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

Вниз

Thread: WinXP+Synchronize=Дружба.   Найти похожие ветки 

 
Idiliya ©   (2004-05-26 10:18) [0]

Привет всем! Вопрос по Thread. Мне стало известно, что WinXP не дружит с Synchronize.
В моей программе пришлось сделать опцию, где пользователь должен указать, работает ли он в WinXP, или в другой операционной системе.
В нитке использую для этого следующий код:
//====================================================
procedure ThreadRun.Execute;
BEGIN
 Repeat
   if NOT gfWinXP then  Synchronize(DoRun) else DoRun;  (* for XP *)
 Until Terminated;
END; {Execute}


Если у пользователя (например, у моего научного руководителя) Win9x, то при использовании Synchronize(DoRun) нет никаких проблем.
Для ХР же (у меня) проблемы и в том, и в другом случае:
Если с Synchronize(DoRun), то расчеты идут нормально, но прорисовка графиков на канве, либо изменения в Label отображаются лишь периодически, небольшими отрывками, затем замирают до следующего раза. Т.е. наблюдать за процессом очень неудобно, приходится часто использовать запрограммированную «паузу», чтобы временно остановить процесс. Тогда все прорисовывается и можно сделать какие-либо пометки по поводу происходящего на форме.
Если без Synchronize, то все отображается прекрасно, но иногда вылетает с сообщением «Project … raised exception class EInvalidOperation with message ‘Canvas does not allow drawing’» и выходит на текст программы, где я использую BitMap на строку  «TheBitMapZ.Free». Либо просто некорректно работает с компонентами на форме. Например, когда используется кнопка «Пауза», в ней не просто приостанавливается нить, но и регулируются доступы к остальным кнопкам (к той же «Запуск» хотя бы). Так вот процесс приостанавливается, но Enabledы не срабатывают.
Вот такие пирожки… Вопроса, собственно, два:
1) Есть ли другой способ укротить WinXP?
2) Как в отчете (это курсовая работа) грамотно объяснить происходящее?


 
Digitman ©   (2004-05-26 10:25) [1]


> Мне стало известно, что WinXP не дружит с Synchronize


полная ерунда

любопытно было бы глянуть , что у тебя творится в теле DoRun()


 
Reindeer Moss Eater ©   (2004-05-26 10:29) [2]

> Мне стало известно, что WinXP не дружит с Synchronize

Дружит. Но только если программист дружит с головой.

любопытно было бы глянуть , что у тебя творится в теле DoRun()
А разницы большой нет. Там же весь OnExecute целиком и полностью.


 
Gero ©   (2004-05-26 10:37) [3]


> WinXP+Synchronize=Дружба

=Love :)


 
Idiliya ©   (2004-05-26 10:42) [4]


> Digitman ©   (26.05.04 10:25) [1]

Хорошо, если Вы правы.
Еще лучше, если Вы действительно согласитесь взглянуть на код.
Но в DoRun вызываются процедуры со всех модулей программы.
Т.е. я могла бы выслать на анализ всю программу целиком.
Если Вы действительно уверены в том, что говорите.


 
Sandman25+1   (2004-05-26 10:47) [5]

Idiliya ©   (26.05.04 10:18)

В таком виде, как Вы написали, Thread совсм не нужен - ведь все равно весь код выполняется главным потоком.


 
Idiliya ©   (2004-05-26 10:54) [6]


> Sandman25+1   (26.05.04 10:47) [5]

А как же тогда заставить все выполнятся в цикле долго и упорно со всеми паузами и проч.?
Ведь таймер не подходит для этого, потому что внутри идет расчет физических процессов, на каждый круг может понадобиться либо больше, либо меньше одной секунды...
Разве еще что-то есть кроме Thread???
Буду очень признательна.


 
Sandman25+1   (2004-05-26 10:56) [7]

[6] Idiliya ©   (26.05.04 10:54)

Нужно запомнить все нужные параметры внутри Thread, чтобы не пришлось обращаться к форме. Тогда расчет можно делать без synchronize, и поток действительно будет полезен.


 
Digitman ©   (2004-05-26 10:58) [8]


> Idiliya ©   (26.05.04 10:42) [4]


> могла бы выслать на анализ всю программу целиком


не стОит, думаю
проще обозначить ЗДЕСЬ участки кода (и примерную схему их вызова), где происходят вычисления табличных данных графика и где происходят обращения к объектам формы для собственно вызуализации расчитанных табл.данных

суть лог.ошибки и так видна - бессмысленно синхронизировать расчеты, синхронизировать следует лишь вывод ГОТОВЫХ рез-тов расчета на канву VCL-контрола


> Если Вы действительно уверены в том, что говорите


насчет "дружбы" или "вражды" ? а почему бы мне не быть в уверенном в том, что механизм оконных сообщений на всех реализациях Win32-платформы (будь то Win9x или ХР/NT/2000) един, и что ни какой "дружбе" или "вражде" вообще не может идти речи, а речь должна идти о ресурсоемкости конкретного приложения и конкретной аппаратно-программной конфигурации/настройке системы (под упр. которой стартует это приложение) в целом ?


 
panov ©   (2004-05-26 10:58) [9]

>Idiliya ©   (26.05.04 10:54) [6]

Syncronize нужно вызывать только в момент необходимости обновления данных в другом потоке.

Т.е. выглядеть это должно так:

procedure ThreadRun.Execute;
BEGIN
Repeat
  Calculate(...); //здесь выполняются все расчеты
                  //и только после окончания расчетов выполняется
  Synchronize(DoRun); //в DoRun должно быть только
                      //обновление данных

Until Terminated;
END; {Execute}


 
pasha_golub ©   (2004-05-26 10:59) [10]

Idiliya ©   (26.05.04 10:54) [6]

Прошу не понимать меня привратно. Мадам, Вы абсолютно не дружите с матчастью.

Для более глубокого (тесного ;-) взаимодействия потрудитесь написать, что делает Ваша программа, зачем понадобился поток, и где Вы прочитали изумительную вещь про недружбу Synchronize & XP?

С уважением.


 
Idiliya ©   (2004-05-26 11:04) [11]

Ладно, ребята, благодарю.
Постараюсь через время привести схему того, что у меня происходит.
Про "недружбу" мне рассказал Научный руководитель.
Встретимся через время, ОК?


 
Idiliya ©   (2004-05-26 11:05) [12]

Ладно, ребята, благодарю.
Постараюсь через время привести схему того, что у меня происходит.
Про "недружбу" мне рассказал Научный руководитель.
Встретимся здесь же, ОК?


 
Reindeer Moss Eater ©   (2004-05-26 11:13) [13]

Про "недружбу" мне рассказал Научный руководитель.

Про таких надо говорить Научный Руководитель


 
Anatoly Podgoretsky ©   (2004-05-26 11:19) [14]

Точно не дружит, поскольку XP и 9x ничего не знают про Дельфи.


 
Reindeer Moss Eater ©   (2004-05-26 11:26) [15]

Ладно, ребята, благодарю.
Постараюсь через время привести схему того, что у меня происходит.


Все и так предельно ясно.
1. Есть проблема с Synchronize
2. Synchronize появился в связи с тем, что применен вторичный поток
3. Весь OnExecue у потока обернут в Synchronize
4. Весь код этого потока выполняется в контексте главного потока.
5. Этот вторичный поток не нужен
6. Значит не нужен Synchronize
7. Значит нет проблемы.


 
Думкин ©   (2004-05-26 11:36) [16]


> Idiliya ©   (26.05.04 10:18)  
> В моей программе пришлось сделать опцию, где пользователь  должен указать, работает ли он в WinXP, или в другой операционной системе.

А заглянуть в кладовку и не мучать пользователей такими опциями?


 
pasha_golub ©   (2004-05-26 11:40) [17]

Думкин ©   (26.05.04 11:36) [16]

Нет, пользователь должен разделять груз ответственности наравне с разработчиком. Как говорится: "ты мне - я тебе". :-)


 
Smithson ©   (2004-05-26 11:40) [18]

К тому, по крайней мере в D5 рисование на канве всегда потокобезопасно. То есть синхронайз для вывода графика не нужен вовсе.


 
pasha_golub ©   (2004-05-26 11:46) [19]

Да что вы говорите?!

А метод TCanvas.Lock мне наверно в пьяном бреду приснился? И не только мне, а и Тейксере с Пачеко?


 
Игорь Шевченко ©   (2004-05-26 12:55) [20]


> Про "недружбу" мне рассказал Научный руководитель.


Сочувствую


 
Digitman ©   (2004-05-26 13:50) [21]


> Idiliya ©   (26.05.04 10:18)


вот псевдокод скелета классического решения твоей задачи

procedure ThreadRun.DoRenderImage(Canvas: TCanvas; Params: TSomeParams);
begin
... здесь в соответствии с параметрами Params строим таблицу и рисуем по ней график на канве Canvas
end;

тело ThreadRun.DoRefreshFormCanvas():

Form1.Canvas.Draw(0,0, FBitMap); //одним махом делаем копию уже готового содержимого врем.битмапа на канве формы

тело ThreadRun.Execute():

FBitMap := TBitmap.Create; // FBitMap - временный битмап, приватное поле класса ThreadRun
try
.. здесь настраиваем параметры битмапа, если нужно
while not Terminated do
 begin

  DoRenderImage(BitMap.Canvas, параметры_графика); // строим и рисуем очередной график на канве временного битмапа БЕЗО ВСЯКОЙ СИНХРОНИЗАЦИИ, ибо никаких обращений к контролам формы при этом не происходит

  Syncronize(DoRefreshFormCanvas); // а вот теперь, когда битмап готов к визуализации, ОБЯЗАТЕЛЬНО синхронизируем с осн.код.потоком отрисовку этого битмапа на канве формы !!
 end;
finally
FBitMap.Free;
end;


 
Idiliya ©   (2004-05-26 14:29) [22]

Короткая схема.
Изучается поведение жидкости в заданных условиях.
Исследуются скорости U,W,Q использующие при расчетах давление (Р) жидкости на стенки сосуда. Визуализируются именно эти скорости, позволяющие наблюдать за поведением жидкого контура.

В процедуре DoRun вертится следующая смесь:

UWQ_FGH;  //вспомогательная процедура, рассчитывающая правые части U,W,Q, используя значения этих же U,W,Q с предыдущего шага.
FFT_SOR; //расчет давления Р одним из выбранных методов. Использует U,W,Q с предыдущего шага.
UWQ; //собственно расчет U,W,Q с использованием правых частей FGH и только что посчитанным давлением Р.
Inc(g_Num_Thread);   // N=N+1 счетчик шагов нити
AddONMFormDinamic; //процедура, которая отображает на форме изменяющиеся от шага к шагу Labelки, Editы, помогающие отображать значения скоростей и проч.
Дальше идет графика. Три процедуры, три канвы, три BitMapa. И всё.
  draw_constR; //график скоростей при фиксированном Х
  draw_constZ;  //график скоростей при фиксированном Y
  draw_UW;      //график функции тока скоростей U,W
В каждой из этих трех процедур при вызове создается BitMap, все рисуется в него и в конце процедуры передается на канву, а BitMap освобождается.

У меня лишь ОДНА нить. Она вертит DoRun и таким образом все работает.


 
Idiliya ©   (2004-05-26 14:32) [23]


> pasha_golub ©   (26.05.04 10:59) [10]

Согласна, что я не программист. Я ведь только учусь.
Пойду в кладовку, как советует Думкин ©   (26.05.04 11:36) [16], пороюсь, постараюсь найти что-то, что само будет определять, что у пользователя за ОС.
Но ведь не в этом проблема.
Под 9х все прекрасно работает с синхронайзом, не смотря на то, что она не знает о Дельфи (Толику). А без него [synhronize] – плохо.
Под ХР же раз на раз не приходится. Без синхронайза лучше и быстрее, но может вылететь, а может и не вылететь. Даже чаще не вылетает. Мне хотелось бы исключить вылет вообще.
Вы все считаете, что проблемы не существует. Хорошо. Я это принимаю.
Программу отдаю на рецензию, где нет ПК с ХР. Могу вообще не освещать этот вопрос и убрать вариант с операционными системами. Что с меня, студеня, взять?
Хотелось просто разобраться и действительно чему-то научиться…


 
Игорь Шевченко ©   (2004-05-26 14:36) [24]

Могу предложить посмотреть, как устроен пример http://www.schevchenko.net.ru/SRC/SuperMarket_50.zip

Под WinXP прекрасно работает :)


 
Idiliya ©   (2004-05-26 14:37) [25]


> Digitman ©   (26.05.04 13:50) [21]

Благодарю за пищу для ума.
Подскажите, что значит таблица с параметрами?
Это массив со значениями для графика?


 
Digitman ©   (2004-05-26 15:20) [26]


> что значит таблица с параметрами?
> Это массив со значениями для графика?


у массива нет параметров

параметры есть у программной ф-ции, которая по этим параметрам формирует результирующий массив точек, по которым строится результ.график

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


 
Reindeer Moss Eater ©   (2004-05-26 15:24) [27]

Под 9х все прекрасно работает с синхронайзом, не смотря на то,

Прикол ситуации в том, что ТАКОЙ вторичный поток с ТАКИМ Execute не нужен на 9x (и на XP тоже).
Поэтому если все замечательно работает на 9х, то можно смело убирать вторичный поток а цикл
repeat
 DoRun;
until need_to_work;

переносить в главный поток.


 
Idiliya ©   (2004-05-26 20:14) [28]

Олень, вот честное слово, я так же спрашивала вначале: зачем для этого нитка, почему нельзя крутить так прямо? Мне было напряжно тогда искать информацию про Thread (Интернет у меня не так давно).
Научный Руководитель сказал «НАДО». И я ему верю.
Пусть будет так.
Здесь сказали достаточно много, мне есть над чем подумать и с чем поиграть.
Всем и каждому персональное спасибо.
Считаю вопрос закрытым.
Еще раз всех благодарю.


 
Idiliya ©   (2004-05-27 11:30) [29]

Попробовала ВСЕ.

> Reindeer Moss Eater ©   (26.05.04 15:24) [27]


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

WinXP действительно дружит с Sinhronize, если в него не пихать все то, что я тогда в него засунула.
Достаточно отдельные процедуры, которые действительно надо синхронизировать.
Реализовала так, как привел пример
> panov ©   (26.05.04 10:58) [9]

:)
Спасибо еще раз за внимание.


 
Digitman ©   (2004-05-27 11:43) [30]


> протекания процесса расчетов


вот для этого трэды и предназначены в первую очередь

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

основной же трэд имеет самой первой и главной задачей - реагировать на события пользовательского ввода и вывод результатов работы различных алгоритмов


 
Reindeer Moss Eater ©   (2004-05-27 11:43) [31]

то как тогда остановить бесконечную процедуру?

Точно так же, как раньше останавливался цикл repeat/until во вторичном потоке. С помощью флага.


 
Idiliya ©   (2004-05-27 19:59) [32]


> Reindeer Moss Eater ©   (27.05.04 11:43) [31]

Хорошо, спрошу еще конкретнее:
Как поменять значение флага, если форма не реагирует на нажатие кнопки?


 
Romkin ©   (2004-05-27 20:33) [33]

Чтобы форма реагировала на нажатия кнопок, достаточно в цикле вычислений периодически вызывать Application.ProcessMessages


 
panov ©   (2004-05-27 21:30) [34]

>Idiliya ©   (27.05.04 11:30) [29]

Как я понял из задачи, процесс вычисления значения для отрисовки графика занимает довольно продолжительное время, поэтому самое эффективное решение - использование для вычислений отдельный поток.

Но если хочется сделать все в основном потоке отделной процедурой, то можно, как уже писали выше, воспользоваться для выхода из зацикленной процдуры флажком, а для того, чтобы форма отвечала на действия пользователя - Application.ProcessMessages.

Но
1. Это замедлит вычисления.
2. Будут неприятные эффекты при работе с контролами на форме(например, передвижение формы рывками)...

Вот пример:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Button3: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure Button3Click(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 isExit: Boolean;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 isExit := False;
 while True do
 begin
   Sleep(1000); //имитируем вычисления
   Application.ProcessMessages;
   if isExit then break;
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 isExit := True;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 ShowMessage("!");
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 isExit := True;
end;

end.



Здесь:
нажатие на Button1 вызывает бесконечный цикл.
нажатие на Button2 прерывает выполнение процедуры Button2Click
нажатие на Button3 вызывает показ информационного окна во время выполнения цикла(прерывет его).

Sleep(1000); - как раз имитирует длительные вычисления, можно поиграться значением задержки, чтобы увидеть эффекты.



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

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

Наверх




Память: 0.58 MB
Время: 0.022 c
4-1083079703
DoG
2004-04-27 19:28
2004.06.06
Закрыть окно !


14-1084984315
Sabak
2004-05-19 20:31
2004.06.06
Нуженли сайт


3-1084795501
Tomkat
2004-05-17 16:05
2004.06.06
FireBird 1.5 и IBX 6.08


1-1085088491
ZedeS
2004-05-21 01:28
2004.06.06
Фокус на Edit


1-1085283375
Demik
2004-05-23 07:36
2004.06.06
Ресурсы -> как работать с ресурсами