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

Вниз

Можно ли воспользоваться WaitForSingleObject таким образом?   Найти похожие ветки 

 
Aleksandr ©   (2002-05-28 14:16) [0]

Есть у меня потомок TList и есть у меня два потока - один добавляет в него объекты, а другой - обрабатывает и удаляет.

Можно ли для второго потока в методе Execute сделать что-нибудь вроде

begin
Repeat
while MyList.Count>0 do begin
Something(MyList.Items[0]);
MyList.Delete(0)
end;
WaitForSingleObject(MyList.Count>0)
until Terminated
end;

То есть чтобы он запускался только при наличии итемов на обработку... Ну слаб я в энтой области пока...


 
Игорь Шевченко ©   (2002-05-28 14:47) [1]

Нет, так делать нельзя.
Но можно завести Event и при добавлении Items в TList взводить этот Event. Соотвественно, обработчик должен ждать этот Event путем WaitForSingleObject

С уважением,


 
NailS ©   (2002-05-28 14:49) [2]

Доступ к данным желательно защитить критической секцией,дабы проблем было поменьше


 
Игорь Шевченко ©   (2002-05-28 14:53) [3]

Или использовать TThreadList, где эта защита уже реализована


 
Aleksandr ©   (2002-05-28 17:06) [4]

2 Nails
То есть нельзя одновременно одним потоком удалять объект из листа, а другим добавлять новый?


 
Игорь Шевченко ©   (2002-05-28 17:09) [5]

Нельзя :-)
Или можно, но результаты при этом будут непредсказуемые


 
Aleksandr ©   (2002-05-28 17:27) [6]

Так... а если я добавление/удаление защищаю критическими секциями, то другой поток будет просто ждать, пока не произойдет "разблокировка" объекта? Или выплюнет Эксепшн?


 
Игорь Шевченко ©   (2002-05-28 17:36) [7]

Будет ждать,конечно. При этом он тоже должен синхронизироваться через critical section.

Но лучше использовать не TList, а TThreadList из classes.pas, где эта синхронизация уже сделана


 
Aleksandr ©   (2002-05-29 09:24) [8]

Опа... да как же им пользоваться?... Он ни Count, ни Delete не имеет...


 
Игорь Шевченко ©   (2002-05-29 10:06) [9]

Дописать его конечно не судьба :-)

Тогда могу предложить свой древний вариант :

unit EList;

interface
uses Windows, Classes;

type
TEList = class
private
hCrit : _RTL_CRITICAL_SECTION;
FList : TList;

function Get(Index : Integer) : Pointer;
procedure Put (Index : Integer; Item : Pointer);
public
constructor Create;
destructor Destroy; override;

procedure Lock;
procedure Unlock;

function Add (Item : Pointer) : Integer;
function Delete (Item : Pointer) : Integer;
function Count : Integer;
function IndexOf (Item : Pointer) : Integer;
function NLGet(Index : Integer) : Pointer;
function NLCount : Integer;
function NLAdd (Item : Pointer) : Integer;
procedure NLClear;

property Items [No : Integer] : Pointer read Get write Put; default;
end;

implementation

constructor TEList.Create;
begin
InitializeCriticalSection(hCrit);
FList := TList.Create;
end;

destructor TEList.Destroy;
begin
DeleteCriticalSection(hCrit);
FList.Free;
end;

procedure TEList.Lock;
begin
EnterCriticalSection(hCrit);
end;

procedure TEList.Unlock;
begin
LeaveCriticalSection(hCrit);
end;


function TEList.Get(Index : Integer) : Pointer;
begin
Lock;
try
Result := FList[Index];
finally
Unlock;
end;
end;

procedure TEList.Put (Index : Integer; Item : Pointer);
begin
Lock;
try
FList[Index] := Item;
finally
Unlock;
end;
end;

function TEList.Add (Item : Pointer) : Integer;
begin
Lock;
try
try
Result := FList.Add(Item);
except
Result := -1;
end;
finally
Unlock;
end;
end;

function TEList.Delete (Item : Pointer) : Integer;
var I : Integer;
begin
Lock;
try
I := FList.IndexOf(Item);
FList.Delete(I);
Result := I;
finally
Unlock;
end;
end;

function TEList.Count : Integer;
begin
Lock;
try
Result := FList.Count;
finally
Unlock;
end;
end;

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

function TEList.NLCount : Integer;
begin
Result := FList.Count;
end;

function TEList.NLAdd (Item : Pointer) : Integer;
begin
try
Result := FList.Add(Item);
except
Result := -1;
end;
end;

function TEList.IndexOf (Item : Pointer) : Integer;
begin
Lock;
try
Result := FList.IndexOf(Item);
finally
Unlock;
end;
end;

procedure TEList.NLClear;
begin
FList.Clear;
end;

end.

С уважением,


 
Digitman ©   (2002-05-29 10:08) [10]

см. TThreadList.LockList/UnlockList



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

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

Наверх




Память: 0.49 MB
Время: 0.014 c
1-30761
EternalWonderer
2002-05-30 15:12
2002.06.10
Автоматическое закрытие Word после печати.


1-30841
MasterA
2002-05-29 10:23
2002.06.10
MOVE


14-30990
MemoryLeak
2002-05-07 09:40
2002.06.10
Чужое адресное пространство.


6-30963
MMarat
2002-03-28 12:05
2002.06.10
Запись в филе на сервак


1-30872
Magic
2002-05-28 17:21
2002.06.10
Независимая работа процедуры