Форум: "Основная";
Текущий архив: 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