Форум: "Основная";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
ВнизЗашищаем данные в потоках Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.04 c