Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
1-1213889970
ggg
2008-06-19 19:39
2009.09.06
Отложенное освобождение объектов


2-1246969271
Алексей111
2009-07-07 16:21
2009.09.06
Table is read only


2-1245070048
pest
2009-06-15 16:47
2009.09.06
программно вырезать указанный файл в буфер обмена


2-1246712483
Incognito
2009-07-04 17:01
2009.09.06
Как сделать Combobox и DateTimePicker только readonly


3-1226639341
rar
2008-11-14 08:09
2009.09.06
Длинная строка





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