Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.06.10;
Скачать: [xml.tar.bz2];

Вниз

Можно ли воспользоваться 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.006 c
3-30687
krotik
2002-05-17 09:58
2002.06.10
Хранимая проца не возвращает набор данных


1-30760
Kordel
2002-05-30 17:01
2002.06.10
Редактирование текста в ячейках StringGrid а


3-30717
Валя
2002-05-18 15:36
2002.06.10
Хелп!!!


1-30908
Alexey_
2002-05-17 17:38
2002.06.10
Как удалить директорию под Windows NT


14-30979
Kozhanov
2002-05-06 12:07
2002.06.10
Help-файлы





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