Форум: "Начинающим";
Текущий архив: 2009.10.25;
Скачать: [xml.tar.bz2];
ВнизРеализация списка в многопоточном приложении Найти похожие ветки
← →
sanx (2009-08-25 03:11) [0]Создаю класс наследник от TList
type
PRule = ^TRule;
TRule = record
ID: Integer;
Filter1: AnsiString;
Filter2: AnsiString;
// ...
end;
TRules = class(TList)
private
protected
procedure Notify(Ptr: Pointer; Action: TListNotification); override;
public
constructor Create(DefaultRule: TRule);
procedure Add(Rule: TRule);
function Find(ID: Integer): Integer; overload;
function Find(Filter1, Filter2: AnsiString): Integer; overload;
end;
implementation
procedure TRules.Add(Rule: TRule);
var
NewRule: PRule;
begin
New(NewRule);
System.Move(Rule, NewRule^, SizeOf(TRule));
inherited Add(NewRule);
end;
constructor TRules.Create(DefaultRule: TRule);
begin
Add(DefaultRule);
end;
function TRules.Find(ID: Integer): Integer;
var
I: Integer;
begin
Result := -1;
for I := 0 to Count - 1 do
if PRule(Items[I])^.ID = ID then begin
Result := I;
Break;
end;
end;
function TRules.Find(Filter1, Filter2: AnsiString): Integer;
var
I: Integer;
begin
Result := -1;
for I := 0 to Count - 1 do
if (PRule(Items[I])^.Filter1 = Filter1)
and (PRule(Items[I])^.Filter2 = Filter2) then begin
Result := I;
Break;
end;
end;
procedure TRules.Notify(Ptr: Pointer; Action: TListNotification);
begin
if Action = lnDeleted then Dispose(Ptr);
inherited Notify(Ptr, Action);
end;
Но как сделать его потокобезопасным? Изменяется список только из главного VCL-потока. А вот чтение нужно сделать безопасным для нескольких рабочих потоков.
← →
sanx (2009-08-25 03:28) [1]Можно использовать Критические секции для блокировки списка при любом доступе к нему, но читать то можно позволить и нескольким сразу, а изменения не часто делаются, их через GUI пользователь делает. Вот в чем для меня сложность.
А вот кое-какие мысли есть:
- Использовать обьект ядра - событие, при любом изменении списка устанавливать в занято.
- Добавить метод Wait. При попытке чтения вызвать метод Wait, который будет ждать событие из первого пукта, если нужно конечно, иначе сразу вернет результат.
Но тут проблема: как начать изменения, именно в тот момент когда никто не читает? Еще одно событие? ) Которое уже устанавливается при попытки чтения? :)
← →
MBo © (2009-08-25 05:48) [2]TMultiReadExclusiveWriteSychronizer можно использовать
← →
Kolan © (2009-08-25 10:00) [3]Есть
TThreadList
— как раз потоко безопасный список.
← →
Leonid Troyanovsky © (2009-08-25 10:29) [4]
> Kolan © (25.08.09 10:00) [3]
> Есть TThreadList — как раз потоко безопасный список.
Читателей много - писатель один. Как раз для этого [2].
Правда, его обновленную в D5? версию не исследовал,
а раньше замечен был в дедлоках.
--
Regards, LVT.
← →
sanx (2009-08-25 18:07) [5]Да спасибо, TMultiReadExclusiveWriteSychronizer то что нужно, вот еще нашел http://www.sql.ru/forum/actualthread.aspx?tid=603799
В инете много обсуждений по поводу TMultiReadExclusiveWriteSychronizer и его глючности и дедлоков, и все вроде соглашаются с тем что начиная с Delphi 7 этот класс стал вести себя очень хорошо. Но для меня не совсем понятно почему метод BeginWrite описан как функция с результатом Boolean? Из описания не пойму ничего. Нужно проверять этот результат? А что делать если False?
← →
Loginov Dmitry © (2009-08-25 21:20) [6]> Но для меня не совсем понятно почему метод BeginWrite описан
> как функция с результатом Boolean? Из описания не пойму
> ничего. Нужно проверять этот результат? А что делать если
> False?
В VCL нигде этот результат не анализируется. Так что можешь без
проверки результата. Имхо, если вернет False, то считай, что тебе
удалось взломать этот самый синхронайзер :)
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.10.25;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.052 c