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

Вниз

Синхронизация в потоке   Найти похожие ветки 

 
Fedia   (2004-09-15 10:11) [0]

Вопрос такой.
Есть две процедуры. Например


procedure Second(Label1: TLabel);
begin
 Label1.Caption:="тест";
end;

procedure First(Label1: TLabel);
begin
 Second(Label1);
end;


Процедура First вызывается в потоке:


procedure TSQLThrd.Execute;
begin
 First(Form1.Label1);  
end;


Без синхронизации не безопасно менять свойства визуальных компонентов. Как мне произвести синхронизацию изменения заголовка Label1?


 
Defunct ©   (2004-09-15 10:13) [1]

Synchronize F1


 
TUser ©   (2004-09-15 10:24) [2]

Да еще написать Form1.Label1, а то компилятор будет ругаться


 
Fedia   (2004-09-15 10:26) [3]

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


 
Суслик ©   (2004-09-15 10:32) [4]


> к сожалению, нужна помощь.

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

Делаешь просто:
1) Выделяешь 10 минут времени.
2) Обдумываешь вопрос (что надо получить, что уже сделал и пр.).
3) Выделяешь еще 10 минут.
4) Аккуратно его записываешь.
5) Ждешь ответа.

Тебя удивит тот факт, что ты получишь нормальный и полезный ответ.
Проверь.


 
panov ©   (2004-09-15 10:38) [5]

>Fedia   (15.09.04 10:11)
Вот вчера писал, разбери пример и поймешь.


unit uSimpleTimer;

interface

uses
 Classes,windows;

type
 TProcTimer = procedure;
 TSimpleTimer = class(TThread)
 private
   FCS: RTL_CRITICAL_SECTION;
   FInterval: Integer;
   FOnTimer: TProcTimer;
   procedure FTimer;
   procedure SetOnTimer(Proc: TProcTimer);
 protected
   procedure Execute; override;
 public
   constructor Create(const aInterval: Integer);
   destructor Destroy;override;
   procedure Timer;
   property OnTimer: TProcTimer write SetOnTimer;
   procedure Start;
   procedure Stop;
   procedure Release;
 end;

implementation

procedure TSimpleTimer.Release;
begin
 Terminate;
 Resume;
end;

destructor TSimpleTimer.Destroy;
begin
end;

constructor TSimpleTimer.Create(const aInterval: Integer);
begin
 inherited Create(True);
 FreeOnTerminate := True;
 FInterval := aInterval;
end;

procedure TSimpleTimer.Start;
begin
 Resume;
end;

procedure TSimpleTimer.Stop;
begin
 Suspend;
end;

procedure TSimpleTimer.SetOnTimer(Proc: TProcTimer);
begin
 FOnTimer := Proc;
end;

procedure TSimpleTimer.Timer;
begin
 FOnTimer;
end;

procedure TSimpleTimer.FTimer;
begin
 if Assigned(FOnTimer) then
 begin
   EnterCriticalSection(FCS);
   FOnTimer;
   LeaveCriticalSection(FCS);
 end;
end;

procedure TSimpleTimer.Execute;
begin
 InitializeCriticalSection(FCS);
 try
   while not Terminated do
   begin
     Sleep(FInterval);
     if Terminated then Continue;
     FTimer;
   end;
 finally
   DeleteCriticalSection(FCS);
 end;
end;

end.


Вызов:


procedure MyOnTimer;
begin
 fMain.sbMain.Panels[0].Text := FormatDateTime("dd.mm.yyyy hh:nn:ss",now);
end;

procedure TfMain.FormCreate(Sender: TObject);
begin
 ST := TSimpleTimer.Create(1000);
 ST.OnTimer := MyOnTimer;
 ST.Timer;
 ST.Start;
end;

procedure TfMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 ST.Release;
end;



 
Erik1 ©   (2004-09-15 10:57) [6]

To panov
Чегото я синхронизации невижу?


 
panov ©   (2004-09-15 10:59) [7]

>Erik1 ©   (15.09.04 10:57) [6]
см. procedure TSimpleTimer.FTimer;


 
Erik1 ©   (2004-09-15 11:15) [8]

И как соотносится вход и выход в критическую секцию с синхнонизацией главного потока? При выполнении этого кода возможна ошибка. Cнхнонизация делается с использованием Synchronize или PostMessage.


 
TUser ©   (2004-09-15 11:17) [9]

Если хочешь через Synchr, не прописывая явно критические секции - то он вызывается из любого метода потока, который м.б. вызван из Execute. Особой разницы в его использовании нет. Другой вопрос - если все написано как у тебя в топике, т.к. First и Second - просто процедуры, а не методы класса. Они тогда ничего не знают про Synchronize, т.к. этот метод - из TThtread"а. Сделай их методами, и все будет хорошо.

PS. Интересно, я угадал в чем проблема?


 
TUser ©   (2004-09-15 11:21) [10]


> Erik1 ©   (15.09.04 11:15) [8]

S сам использует критические секции.


 
panov ©   (2004-09-15 11:27) [11]

>Erik1 ©   (15.09.04 11:15) [8]
Посмотри исходный код Synchronize


 
Fedia   (2004-09-15 11:40) [12]

Я тут погрузился в разбор кода и был временно не доступен :)
TUser ©   (15.09.04 11:17) [9]
>> PS. Интересно, я угадал в чем проблема?
Мне интересно о чем тут было гадать? Хотя похоже ты не один гадал, следовательно косяк мой.
Я не могу переделывать все процедуры в методы потока. Слишком много кода придется менять. Поэтому хотел изобрести хитрую ссылку на  Synchronize, чтобы заменить все строки типа:
Label1.Caption:="новый заголовок" на например
MySync(Label1, "новый заголовок"), где MySync - процедура, в которой происходит синхронизация.

А на счет входа в критические секции сейчас попробую часть кода переделать и запустить на ночное тестирование. Если не упадет, переделаю остальное.


 
panov ©   (2004-09-15 11:45) [13]

>All
Код [5] некорректен, так как эту критическую секцию должны использовать все потоки при обращении к VCL.


 
Erik1 ©   (2004-09-15 15:11) [14]

To panov
С этим полностью согласен, добавлю, что во все входит и главный поток.

To TUser
Ты сам смотрел Synchronize? Незаметил случайно вот такю строку SendMessage(ThreadWindow, CM_EXECPROC, 0, Longint(Self)) ? В Synchronize посылается сообщение созданому окну, а в обработчике сообщений ищется CM_EXECPROC и вызывается нужный метод. Поэтому Synchronize просто использует очередь сообщенией для синхронизации.


 
Fedia   (2004-09-16 01:28) [15]

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

 TSQLThrd2 = class(TThread)
 protected
   Label1: TLabel;
   LCaption: String;
   PB: TGaugeCX; //это видоизмененный ProgressBar
   Position: Integer;
 public
   procedure ChengLabel;
   procedure ChangePB;
 end;

var
 TSQLThrd: TSQLThrd2;


Процедуры, в которых происходит изменение свойств визуальных компонентов

procedure TSQLThrd2.ChengLabel;
begin
 Label1.Caption:=LCaption;
end;

procedure TSQLThrd2.ChangePB;
begin
 PB.Position:=Position;
end;

Процедуры, в которых происходит синхронизация с основным потоком:

procedure MyLabelSynchronize(Label1: TLabel; s: String);
begin
 TSQLThrd.Label1:=Label1;
 TSQLThrd.LCaption:=s;
 TSQLThrd.Synchronize(TSQLThrd, TSQLThrd.ChengLabel);
end;

procedure MyPBSynchronize(PB: TGaugeCX; i: Integer);
begin
 TSQLThrd.PB:=PB;
 TSQLThrd.Position:=i;
 TSQLThrd.Synchronize(TSQLThrd, TSQLThrd.ChangePB);
end;


А вот замена процедуры Second из (15.09.04 10:11):  

procedure Second(Label1: TLabel);
begin
 //Label1.Caption:="тест"; //без синхронизации
 MyLabelSynchronize(Label1, "тест"); //с использованием синхронизации
end;



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

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

Наверх




Память: 0.49 MB
Время: 0.035 c
4-1093238628
вразлет
2004-08-23 09:23
2004.10.03
отмена выключения компьютера


3-1094369250
3APA3A
2004-09-05 11:27
2004.10.03
Изменение домена


3-1094535962
Senator
2004-09-07 09:46
2004.10.03
RxDBLookupCombo


1-1095342962
stud
2004-09-16 17:56
2004.10.03
необходимо выделить фрагмент изображения


14-1095059759
вразлет
2004-09-13 11:15
2004.10.03
выравнивание данных





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