Форум: "WinAPI";
Текущий архив: 2009.09.06;
Скачать: [xml.tar.bz2];
ВнизРабота с протоками Найти похожие ветки
← →
EgorovAlex (2007-11-29 11:58) [0]При работа с потоками очень часто можно видеть такие примеры:
procedure Test;
begin
CreateThread(...);
end;
Но здесь налицо утечка ресурсов - хендлов созданных потоков.
Сейчас я делаю так:
procedure Test;
var
hThread: Cardinal;
begin
hThread := CreateThread(...);
if (hThread > 0) then
CloseHandle(hThread);
end;
Теперь утечки нет, и всё нормально работает, но корректно ли закрывать хендл потока до его завершения? Если нет, тот как лучше делать?
← →
guav © (2007-11-29 12:01) [1]Закрывать действительно надо.
Закрывать до завершения потока корректно.
Проверять лучше hThread <> 0, а хендл объявлять как THandle.
Лучше использовать BeginThread вместо CreateThread чтобы неявно выставлять IsMultiThread в True
← →
tesseract © (2007-11-29 12:05) [2]А смысл такой процедуры ?
Для того чтобы понять работает поток или нет в него передаеться Event или их массив. При выходе потокам посылаеться соббщение "выключайся" и ждеться срабатывание WaitForMultipleObjects. Пример есть в справке delphi и MSDN.
← →
EgorovAlex (2007-11-29 12:12) [3]to tesseract:
очень часто есть потоки, время жизни которых значительно меньше времени жизни приложения, и они создаются очень часто. Если это будет в сервисе, когда компьютер месяцами не выключается, до утечка хендлов "положит" сервер.
to guav:
THandle=LongWord(=Cardinal)
а кардинал не может быть отрицательным
← →
Сергей М. © (2007-11-29 12:19) [4]
> При работа с потоками очень часто можно видеть такие примеры:
> CreateThread(...);
Плохие примеры.
BeginThread следует использовать, иначе грабли рано или поздно неминуемы.
← →
tesseract © (2007-11-29 14:09) [5]
> очень часто есть потоки, время жизни которых значительно
> меньше времени жизни приложения, и они создаются очень часто.
>
Плохой пример. Потоки не должны создаваться и разрушаться за просто так. Использование таких "потоков" только снижает производительность, т.к. время на создание потоков затрачиваеться огромное.
← →
EgorovAlex (2007-11-29 14:26) [6]Это понятно, в таких случаях оптимальным будет пул потоков.
Кстати может кто-нибудь объяснить, что можно делать с Queue для TThread (Delphi 2007)
← →
Сергей М. © (2007-11-29 14:45) [7]Тоже что и с любой другой очередью.
Очередь - она и в Африке очередь)
← →
EgorovAlex (2007-11-29 14:48) [8]А для чего добавлена эта очередь? Как её использовать?
← →
Сергей М. © (2007-11-29 14:54) [9]Понятия не имею. Д2007 не пользую.
Навскидку могу предположить, что это спецнаследник TQueue
← →
tesseract © (2007-11-29 15:01) [10]
> А для чего добавлена эта очередь? Как её использовать?
Я для D7 сам такую писал. Пишешь туда из основного потока данные, а из потоков уже их тарабанишь, из них пишешь в очередь, которая разбираеться основным потоком.
← →
EgorovAlex (2007-11-29 15:21) [11]Нет, это что-то другое. В 2007 появилось 4 новых метода, но они недокументированы:
class procedure Queue(AThread: TThread; AMethod: TThreadMethod); overload;
class procedure RemoveQueuedEvents(AThread: TThread; AMethod: TThreadMethod);
class procedure StaticQueue(AThread: TThread; AMethod: TThreadMethod);
class procedure StaticSynchronize(AThread: TThread; AMethod: TThreadMethod);
← →
Сергей М. © (2007-11-29 15:26) [12]
> В 2007 появилось 4 новых метода
Полагаю, что эти методы опираются на соответствующие нововведения в класс TThread, о коих ты почему-то не проронил ни слова.
← →
EgorovAlex (2007-11-29 15:36) [13]Вот что накопал в исходниках:
class procedure TThread.Queue(AThread: TThread; AMethod: TThreadMethod);
var
LSynchronize: PSynchronizeRecord;
begin
if AThread <> nil then
AThread.Queue(AMethod)
else
begin
New(LSynchronize);
try
LSynchronize.FThread := nil;
LSynchronize.FSynchronizeException := nil;
LSynchronize.FMethod := AMethod;
Synchronize(LSynchronize, True);
finally
if MainThreadID = GetCurrentThreadID then
Dispose(LSynchronize);
end;
end;
end;
В ней вызывается перегруженная Synchronize(LSynchronize, True);
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False);
var
SyncProc: TSyncProc;
SyncProcPtr: PSyncProc;
begin
if GetCurrentThreadID = MainThreadID then
ASyncRec.FMethod
else
begin
if QueueEvent then
New(SyncProcPtr)
else
SyncProcPtr := @SyncProc;
if not QueueEvent then
SyncProcPtr.Signal := CreateEvent(nil, True, False, nil)
else
SyncProcPtr.Signal := 0;
try
EnterCriticalSection(ThreadLock);
try
SyncProcPtr.Queued := QueueEvent;
if SyncList = nil then
SyncList := TList.Create;
SyncProcPtr.SyncRec := ASyncRec;
SyncList.Add(SyncProcPtr);
SignalSyncEvent;
if Assigned(WakeMainThread) then
WakeMainThread(SyncProcPtr.SyncRec.FThread);
if not QueueEvent then
begin
LeaveCriticalSection(ThreadLock);
try
WaitForSingleObject(SyncProcPtr.Signal, INFINITE);
finally
EnterCriticalSection(ThreadLock);
end;
end;
finally
LeaveCriticalSection(ThreadLock);
end;
finally
if not QueueEvent then
CloseHandle(SyncProcPtr.Signal);
end;
if not QueueEvent and Assigned(ASyncRec.FSynchronizeException) then
raise ASyncRec.FSynchronizeException;
end;
end;
← →
Сергей М. © (2007-11-29 15:39) [14]Так ведь из кода все понятно)
Разобраться-то не пытался ?
← →
EgorovAlex (2007-11-29 16:06) [15]Нет, что-то туплю :(
Что это - очередь методов на синхронизацию?
← →
Сергей М. © (2007-11-29 16:27) [16]Из огрызка кода - да, похоже на то.
← →
tesseract © (2007-11-29 16:45) [17]
> Из огрызка кода - да, похоже на то.
Тогда мне идея нравиться.
← →
MetalFan © (2007-12-01 00:12) [18]лучше имхо посмотреть в сторону пулов потоков...
какойнить QueueUserWorkItem
← →
Однокамушкин (2007-12-02 21:35) [19]
> EgorovAlex (29.11.07 14:26) [6]
> Кстати может кто-нибудь объяснить, что можно делать с Queue
> для TThread (Delphi 2007)
Здесь используется тот же механизм, который использует TThread.Synchronize, с одним исключением: Synchronize ставит процедуру в специальную очередь для выполнения главной нитью и ждёт, когда главная нить извлечёт её из очереди и выполнит, а Queue ставит в очередь, но ничего не ждёт: нить, вызвавшая Queue, сразу продолжает работу, а главная нить когда выполнит, тогда и выполнит... Это, если так можно выразиться, асинхронная синхронизация с главной нитью :)))
← →
EgorovAlex (2007-12-02 22:06) [20]to Однокамушкин:
Спасибо, я тоже к такому выводу пришёл
← →
GrayFace © (2008-07-19 00:55) [21]В коде из превого поста еще не хватает вызовов Win32Check. А если без них, то я бы написал CloseHandle(CreateThread(...));
← →
Германн © (2008-07-19 01:00) [22]<offtop>
> GrayFace © (19.07.08 00:55) [21]
>
> В коде из превого поста еще не хватает вызовов Win32Check.
> А если без них, то я бы написал CloseHandle(CreateThread(.
> ..));
>
Оп ля. Как влияет недавно прошедший день рождения на человека!
Некромант, однако :)
(с) sniknik
← →
Игорь Шевченко © (2008-07-21 15:20) [23]
> При работа с потоками очень часто можно видеть такие примеры:
>
>
> procedure Test;
> begin
> CreateThread(...);
> end;
Ну наверное этот код не для сервиса, работающего месяцами. Но вполне допустимый для ряда задач, например таких, где время жизни приложения немногим превышает время работы потока.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2009.09.06;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.006 c