Zdravím,
potřeboval bych poradit s jednou (pro mě) zapeklitou věcí. Jde o následující:
Mám program který dávkově zpracovává obrázky (soubory). Když pominu hlavní vlákno, tak v programu běží řídící vlákno (stará se o seznam souborů ke zpracování, vytváří pracovní vlákna a rozděluje mezi ně práci) a jedno nebo víc pracovních vláken. Nejsem takový frajer abych každý jednotlivý obrázek zpracovával ve více vláknech, takže to vypadá tak, že jedno pracovní vlákno dostane ke zpracování jeden soubor a nějaké další informace, a dál už si jede na vlastním písečku. Po dokončení a uložení výsledku si řekne řídícímu vláknu o další, to mu ho buď přidělí, nebo pokud už jsou všechny zpracovány mu řekne aby se ukončilo.
Toliko k objasnění situace. A teď k problému.
Pracovní vlákno má deklarovanou bitmapu (TBitmap) v sekci private (více viz ukázka kódu dále). Do této bitmapy se načte zpracovávaný soubor, provedou se potřebné úpravy (včetně např. změny velikosti nebo barevné hloubky), a výsledek se uloží. Bitmapa existuje celou dobu co vlákno, čili se pro každý zpracovávaný soubor NEvytváří nová (mám pro to své důvody). Nepřistupuje k ní žádné jiné vlákno než to které ji vytvořilo.
Jenomže program mi při zpracovávání ve více-méně náhodných situacích hlásí chybu, konkrétně nedostatek paměti (EOutOf Resources nebo tak nějak, číslo chyby je 8). MemoryLeak tam ale nikde není (koneckonců program si bere tak maximálně 15MiB RAM, záleží na počtu pracovních vláken). A mě by zajímalo proč tomu tak je. Google moc neporadil, všude se řeší jenom přístup do jedné bitmapy z více vláken - to není tento případ.
ukázka kódu (podstatné věci kolem bitmapy):
TWorkThread = Class(TTHread)
private
thrWorkBitmap: TBitmap;
...
constructor TWorkThread.Create(...
begin
...
thrWorkBitmap := TBitmap.Create;
...
end;
destructor TWorkThread.Destroy;
begin
thrWorkBitmap.Free;
...
end;
procedure TWorkThread.Execute;
begin
//zde pracuji s bitmapou
end;
Prozatím jsem udělal to, že bitmapě zamykám canvas a vytvářím a uvolňuji ji uvnitř procedury Execute, zdá se že to pomáhá. Ale stejně mě nejde do hlavy, proč když k ní přistupuje jenom jediné vlákno, to dělá takovouhle paseku. Budu rád za jakoukoliv radu nebo objasnění.
Snad vás délka mého příspěvku neodradila a dočetli jste až sem :).
Jenom doplním že se považuji za začátečníka (tak mě hned nekamenujte), dělám to na WinXP (32bit) a Delphi 7 Personal.