Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Зашищаем данные в потоках


User1 ©   (2005-06-03 12:20:00) 

Есть класс, который может использоваться в нескольких потоках. Я хочу защищать данные внутри кода класса с помощью критических секций. Вопрос:
Мне необходимо защищать весь общий код или только общие переменные, которые обьявленны в классе.

И как можно защитить VCL обьекты? (Кроме Synchronize).


User1   (2005-06-03 22:51:00) [1]

Fay ©   (03.06.05 18:27) [19]
Извини, но помоему мы говорим о разных вещах.
В твоем способе, если я привяжу на событие класса процедуру в которое будет работа с VCL обьектом - иногда вылетает с ошибкой.


Fay   (2005-06-03 18:27:00) [2]

property OnValueChanged : TOnValueChanged read EventOnValueChanged write SetOnValueChanged;
....

procedure TMyClass.SetOnValueChanged(Value : TOnValueChanged);
begin
 CS.Enter;
 try
   if Value <> EventOnValueChanged then
     EventOnValueChanged := Value;
 finally
   CS.Leave;
 end;
end;


User1   (2005-06-03 17:59:00) [3]

Сори, но опять ошибка:
MyObj := TMyClass.Create;
создается в дополнительном потоке.


User1   (2005-06-03 17:58:00) [4]

перед property OnValueChanged : TOnValueChanged read EventOnValueChanged write EventOnValueChanged;
упустил public


User1   (2005-06-03 17:57:00) [5]

TOnValueChanged = procedure (Sender : TObject; Value : String) of Object;

далее в моем классе:

private
EventOnValueChanged : TOnValueChanged;
property OnValueChanged : TOnValueChanged read EventOnValueChanged write EventOnValueChanged;


Обьект данного класса создан в доп. потоке.

Далее в основном потоке обьявляю:
pocedure OnValueChanged(Sender : TObject; Value : String);

Далее в коде основного потока пишу:

............
MyObj := TMyClass.Create;
Form1.OnValueChanged := MyObj.OnValueChanged;
...........
procedure TForm1.OnValueChanged(Sender : TObject; Value : String);
begin
Form1.Edit1.Text := Value;
end;


И теперь вызываем:

CS.Enter;
try
if Assigned(EventOnValueChanged) then
  EventOnValueChanged(Self,NewValue);
finally
CS.Leave;
end;


И это правильно?
Насколько я знаю - критическую секцию в данном случае использовать нельзя. Обьясните где я не прав.


Fay   (2005-06-03 17:45:00) [6]

Что значит "генерируется", и что значит "метод ... будет в другом потоке"?

Короче. Из кода ясно, что НМТК выполняется в ДП, (4) = True.

Значит EventOnValueChanged нужно зашитить крит. секцией где-нибудь в SetEventOnValueChangeи в НМТК :

CS.Enter;
try
 if Assigned(EventOnValueChanged) then
   EventOnValueChanged(Self,NewValue);
finally
 CS.Leave;
end;


User1   (2005-06-03 17:39:00) [7]

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


User1   (2005-06-03 17:35:00) [8]

4 - Событие EventOnValueChanged геренируется моим классом, но метод, который будет привязан к этому сообытию будет в другом потоке. например в основном.


Fay   (2005-06-03 17:29:00) [9]

2 User1   (03.06.05 17:18) [11]

1) Есть Осн. поток (ОП) и доп. поток (ДП).
2) Экземпляр (ЭТК) твоего класса (ТК) создан в ДП.
3) Код if Assigned(EventOnValueChanged) then EventOnValueChanged(Self,NewValue);
 является частью некоторого метода ТК (НМТК).
4) EventOnValueChanged - свойство, доступное на запись друким классам (ДК)
5) НМТК доступен ДК.

Подтверди или опровергни 1-5.


User1   (2005-06-03 17:18:00) [10]

[10] Fay ©   (03.06.05 17:08)
Ничего не понял. Нужны или не нужны или есть алтернативы


Fay   (2005-06-03 17:08:00) [11]

Спасут. Одни лекарства нужно есть, другие в @опу пихать. Просто не путай.


User1   (2005-06-03 16:34:00) [12]

[8] Fay ©   (03.06.05 16:28)
У меня обьект некого класса находится в доп. потоке. Если я в нем использую:
if Assigned(EventOnValueChanged) then EventOnValueChanged(Self,NewValue);
А это событие идет на изменения значения на форме, то просто критические секции меня как я понял не спасут. Кто может сказать как лучше это сделать?


Fay   (2005-06-03 16:28:00) [13]

2 User1   (03.06.05 16:15) [7]
Вместо попыток правильно сформулировать вопрос (я так и не понял про класс в потоке), почитай про  использование крит. секций. Ответы должны возникнуть сами - от лучшего понимания собственной задачи.


User1   (2005-06-03 16:15:00) [14]

Спасибо.

Еще такая проблема:

В моем классе периодически генерируются события:
if Assigned(EventOnValueChanged) then EventOnValueChanged(Self,NewValue);

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


Digitman   (2005-06-03 12:50:00) [15]


> dmitry501 ©   (03.06.05 12:34) [4]


если имеется threadvar-переменная V, поток А, обращаясь к этой переменной, никогда не "пересечется" с потоком В, обращающимся к этой же переменной

на то они и threadvar, эти переменные


Digitman   (2005-06-03 12:41:00) [16]


> необходимо защищать .. код


"защищать" код нет никакой необходимости, да и защитить его невозможно по определению кодовых потоков

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


> как можно защитить VCL обьекты


никак.

защищаются не собственно VCL-объекты, а обращения к их методам/свойствам (в итоге приводящие к обращениям к тем или иным данным этих объектов)


> Кроме Synchronize


Synchronize придуман, в первую очередь, для защиты визуальныхобъектов, создаваемых и контролируемых ядром VCL

если объект не визуальный (например, TList), то во многих случаях его можно защитить и без Synchronize - с пом., например, крит.секций

при этом ПЕРЕД самым первым обращением к TList (как к объекту потенциально совместного доступа) КС создается как объект, доступный для обращения со стороны кода, исполняемого во всех без исключения потоках процесса, заинтересованных в доступе к TList... перед обращением к TList поток входит в КС, работает с TList и следом безусловно выходит из КС .... основной поток - НЕ исключение, он такой же равноправный поток, как и прочие (дополнительные)


dmitry501   (2005-06-03 12:34:00) [17]

Юрий Зотов ©   (03.06.05 12:30) [3]
А если переменные threadvar, используемые не в классе потока?


Юрий Зотов   (2005-06-03 12:30:00) [18]

Защищается не код, а данные, причем только те данные, которые могут быть общими для нескольких потоков. Поэтому поля самого класса "поток" можно и не защищать - они уникальны для каждого его экземпляра.


User1   (2005-06-03 12:29:00) [19]

dmitry501 ©   (03.06.05 12:26) [1]
а какие именно данные? локальные данные общих процедур тоже надо перекрывать?


dmitry501   (2005-06-03 12:26:00) [20]

User1   (03.06.05 12:20)
критические секции только на изменение данных, которые могут изменятся одновременно несколькими потоками...


Наверх

Титульная страница Поиск, карта сайта Написать письмо