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

Вниз

Thread.OnDestroy   Найти похожие ветки 

 
Slay   (2005-01-18 17:16) [0]

Мне нужно освободить динамически выделенную в потоке память. Я пытаюсь это  сделать в OnDestroy потока но это событие не выполняется. Где ошибка?

Пример:

...
const cfiledeb="Debug.txt";
var SrvThread:PThread;

.......

procedure MyDestroy();
begin
LogFileOutput(cfiledeb,"MyDestroy");
...
end;

procedure CMD();
begin
LogFileOutput(cfiledeb,"CMD");
sleep(1000);
...
end;

procedure TForm1.KOLFormFormCreate(Sender: PObj);
begin
SrvThread:=NewThreadAutoFree(TOnThreadExecute(MakeMethod(nil,@CMD)));
SrvThread.OnDestroy := TOnEvent(MakeMethod(nil,@MyDestroy));
...
end;
....


 
thaddy   (2005-01-18 20:39) [1]

OnDestroy is carried out in the context of the main thread, because the thread itself is already finished and the inherited destroy is called for a Tobj. Here"s a trick: if you allocate memory in the thread do it like this:
type

PMem = ^Tmem;
Tmem=object(Tobj)
protected
 function GetMemory:Pointer;
 procedure Setmemory(const aMemponter:Pointer);
public
 property Memory:Pointer read Getmemory write setmemory;
end;

procedure Tmem.setmemory(const:value:Pointer);
begin
 CustomData:=Value; //Get"s autofree"d
end;

function Tmem.getmemory:Pointer;
begin
 Result:=Customdata;
end;

Usage:

If you allocate memory in the thread:

var
 D:PMem;
begin
 New(D,create);
 Mythread.add2autofree(D) //
 D,memory:=Allocmem(Memsize);
end.


 
thaddy   (2005-01-18 20:45) [2]

with addition:

function Newmemory(aOwner:PThread):PMem;overload;
begin
 New(Result,Create);
 aOwner.add2autofree(Result);
end;

function Newmemory(aOwner:PThread; Size:Cardinal):PMem;overload;
begin
 New(Result,Create);
 aOwner.add2autofree(Result);
 Result.CustomData:=Allocmem(Size);
end;

I just invented this so I hope it works!


 
thaddy   (2005-01-19 02:01) [3]

Sorry, I have tried my example and it does NOT work. NOT in threads, unless you do a lot of extra work.
The tlist that holds the autofree objects is in the main thread and so its not threadsafe to use it from within the thread. But he autofree memory objects itself works! (removing the typo"s first);


 
thaddy   (2005-01-19 02:05) [4]

Here is it, but not for threads:
unit kolautomem;
//
// purpose: Auto freeing memory objects
//  author: © 2004, Thaddy de Koning
// Remarks: Doesn"t work from within threads (without sync).
//          because autofree tlist is in the main thread.
//
interface
uses kol;

type

PAutoMem = ^TAutoMem;
TAutoMem = object(Tobj)
private
 FMemory:Pointer;
 procedure setmemory(const value:pointer);
public
 destructor destroy;virtual;
 property memory:pointer read Fmemory write setmemory;
end;

function NewAutoMem(aOwner:Pobj; Size:Cardinal):PAutoMem;

implementation

{ TAutoMem }
function NewAutoMem(aOwner:Pobj; Size:Cardinal):PAutoMem;
begin
New(Result,Create);
Result.FMemory:=Allocmem(Size); // Clean memory
Result.Add2AutoFree(Result);
end;

destructor TAutoMem.destroy;
begin
 Freemem(Fmemory);
 inherited;
end;

procedure TAutoMem.setmemory(const value: pointer);
begin
  Fmemory:=Value;
end;

end.


 
thaddy   (2005-01-19 02:37) [5]

And finally a solution that works!

grids.pas contains a routine called stackalloc, which allocates memory on the stack. this memory is free"s automatically when the caller exits. If you assign memory using stack alloc in the OnExeute method of the thread, it will be free"d automatically when the tread exits! Maybe that will help! There is an accompanying stackfree method if you do a lot of dynamic allocations/deallocations in the procedure of function.
This works!, tested! Just copy the routines from grid.pas.
(Mind your stack size, increase it if necessary)


 
SPeller ©   (2005-01-19 10:43) [6]

А не проще ли в начале процедуры потока выделить память, а в её конце, перед выходом, освободить?


 
thaddy   (2005-01-19 11:02) [7]

StackAlloc at the beginning of the flow in the thread works ok. You then do not have to free it when the thread exits, because the stackpointer is updated to that before the thread started, thus autofreeing the memory, But for large blocks, I would use an oldstyle synchro object to protect the assignment and the release of memory.


 
Slay   (2005-01-19 12:39) [8]

Большое спасибо за помощь. Почти разобрался



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

Форум: "KOL";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.46 MB
Время: 0.059 c
1-1123213552
Viktop
2005-08-05 07:45
2005.08.28
Изменить высоту элемента в TreeView


4-1121166866
Big Joe
2005-07-12 15:14
2005.08.28
Проблема с флэшкой


14-1123449342
Petr V. Abramov
2005-08-08 01:15
2005.08.28
Водку надо допивать... :)


3-1121416353
DD
2005-07-15 12:32
2005.08.28
Динамический запрос в Оракле 8


1-1123326265
Ivanov
2005-08-06 15:04
2005.08.28
.pak - файлы





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