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

Вниз

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

 
User1   (2005-06-03 12:20) [0]

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

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


 
dmitry501 ©   (2005-06-03 12:26) [1]

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


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

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


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

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


 
dmitry501 ©   (2005-06-03 12:34) [4]

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


 
Digitman ©   (2005-06-03 12:41) [5]


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


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

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


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


никак.

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


> Кроме Synchronize


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

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

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


 
Digitman ©   (2005-06-03 12:50) [6]


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


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

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


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

Спасибо.

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

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

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


 
Fay ©   (2005-06-03 16:28) [8]

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


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

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


 
Fay ©   (2005-06-03 17:08) [10]

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


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

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


 
Fay ©   (2005-06-03 17:29) [12]

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:35) [13]

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


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

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


 
Fay ©   (2005-06-03 17:45) [15]

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

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

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

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



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

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;


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


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

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


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

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


 
Fay ©   (2005-06-03 18:27) [19]

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 22:51) [20]

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



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

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

Наверх




Память: 0.52 MB
Время: 0.044 c
1-1118081025
redlord
2005-06-06 22:03
2005.06.29
регулярные выражения


11-1101102013
Shaman O Mega
2004-11-22 08:40
2005.06.29
Proxies.dcu MCK&amp;KOL


1-1117963373
Mihail
2005-06-05 13:22
2005.06.29
Глупейшая проблема


1-1117706901
Serg1981
2005-06-02 14:08
2005.06.29
Динамическое создание формы


14-1117390746
Ломброзо
2005-05-29 22:19
2005.06.29
"Include" в MS Word