Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.039 c
1-1117812333
sofs
2005-06-03 19:25
2005.06.29
Как сделать одновременный скроллинг в двух ричэдит?


1-1118069208
Эдик Дятлов
2005-06-06 18:46
2005.06.29
Сохранить запись, содержащую динамический массив, в файл


1-1117905720
Агент Х-СОМ
2005-06-04 21:22
2005.06.29
Плохое поведение градиента в Delphi


14-1117696261
Nik8.
2005-06-02 11:11
2005.06.29
Загадка - Два брата


1-1118060645
Goga
2005-06-06 16:24
2005.06.29
Доступ к реестру из службы





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