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

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.044 c
14-1085057631
Соловьев
2004-05-20 16:53
2004.06.06
http://www.grineflip.dk/funstuff/kill/kill.htm#


3-1084454956
Адмирал
2004-05-13 17:29
2004.06.06
Создание БД из приложения или выполнение скрипта


14-1085309453
Serious Sam
2004-05-23 14:50
2004.06.06
Где можно продать свою прогу?


1-1085381901
Галинка
2004-05-24 10:58
2004.06.06
Кто хорошо знает Модуль Math?


4-1083304589
ZHK
2004-04-30 09:56
2004.06.06
Как получить имя принтера





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