2013-03-04 2 views
2

У меня есть внешнее приложение, которое многопоточно, и это приложение использует мою собственную DLL для выполнения некоторых действий из этих потоков.
В этой dll у меня есть 2 функции, которые считывают и записывают некоторые данные в TList.
Мне нужно, чтобы этот список был свободно прочитан этими потоками, но только один может писать за раз, остальные должны ждать своего времени, чтобы написать.Delphi2006 - Есть ли TList с TMultiReadExclusiveWriteSynchronizer?

Мой вопрос:
- есть в BDS 2006 TList компонентов, которые имеют возможность TMREWSync или
- может быть, вы знаете, любой свободный компонент третьих сторон, которые я могу использовать в своем приложении или
- может быть, у вас есть некоторые настраиваемый код TList, который может делать такие вещи, как это упомянуто выше.

Edit: мне нужно что-то вроде TThreadList.LockList, но только для записи в этот список.

Спасибо за любую помощь.

+0

Возможный дубликат [реализация Delphi MREW, который способствует читателям?] (Http://stackoverflow.com/questions/1742915/delphi-mrew-implementation-that-favors-readers) –

+0

Вы не понимаете, мне нужен TList которые имеют возможности MREW, это не тот же вопрос. Существует TThreadList, но он блокирует все, чтение невозможно, пока блокировка не будет удалена. – NevTon

+2

'TMultiReadExclusiveWriteSynchronizer' - это синхронный объект. У него нет контейнера, связанного с ним. Вы должны сделать это немного. Это очень легко сделать. Ты пробовал? –

ответ

2

Это достаточно просто, чтобы собрать TMultiReadExclusiveWriteSynchronizer и TList таким же образом, как TThreadList. Если вы уже знаете, как работают эти классы, вы сможете следовать приведенному ниже коду.

type 
    TReadOnlyList = class 
    private 
    FList: TList; 
    function GetCount: Integer; 
    function GetItem(Index: Integer): Pointer; 
    public 
    constructor Create(List: TList); 
    property Count: Integer read GetCount; 
    property Items[Index: Integer]: Pointer read GetItem; 
    end; 

    TMREWList = class 
    private 
    FList: TList; 
    FReadOnlyList: TReadOnlyList; 
    FLock: TMultiReadExclusiveWriteSynchronizer; 
    public 
    constructor Create; 
    destructor Destroy; override; 
    function LockListWrite: TList; 
    procedure UnlockListWrite; 
    function LockListRead: TReadOnlyList; 
    procedure UnlockListRead; 
    end; 

{ TReadOnlyList } 

constructor TReadOnlyList.Create(List: TList); 
begin 
    inherited Create; 
    FList := List; 
end; 

function TReadOnlyList.GetCount: Integer; 
begin 
    Result := FList.Count; 
end; 

function TReadOnlyList.GetItem(Index: Integer): Pointer; 
begin 
    Result := FList[Index]; 
end; 

{ TMREWList } 

constructor TMREWList.Create; 
begin 
    inherited; 
    FList := TList.Create; 
    FReadOnlyList := TReadOnlyList.Create(FList); 
    FLock := TMultiReadExclusiveWriteSynchronizer.Create; 
end; 

destructor TMREWList.Destroy; 
begin 
    FLock.Free; 
    FReadOnlyList.Free; 
    FList.Free; 
    inherited; 
end; 

function TMREWList.LockListWrite: TList; 
begin 
    FLock.BeginWrite; 
    Result := FList; 
end; 

procedure TMREWList.UnlockListWrite; 
begin 
    FLock.EndWrite; 
end; 

function TMREWList.LockListRead: TReadOnlyList; 
begin 
    FLock.BeginRead; 
    Result := FReadOnlyList; 
end; 

procedure TMREWList.UnlockListRead; 
begin 
    FLock.EndRead; 
end; 

Это самая основная возможность реализации. Если хотите, вы можете добавить еще несколько колоколов и свистков в порядке TThreadList.

+0

Спасибо, но у меня есть еще один вопрос: используя ваше решение, могу ли я заблокировать запись, будучи уже заблокированным для чтения? – NevTon

+0

Вы можете, если 'TMultiReadExclusiveWriteSynchronizer' позволяет это. –

+0

Ситуация с гипотезой: 'with List.LockListRead do try' ... сделать что-то ...' List.LockListWrite.Items [x]: = Nil; List.UnlockListWrite; '... сделать что-то ...' finally List.UnlockListRead; конец; '. Я могу это сделать? – NevTon

Смежные вопросы