[fpc-pascal] Re: Multi-threaded project with few locks (no Thread.waitfor). Memory consumption keeps increasing on Ubuntu 10.10 x64
Vinzent Höfler
JeLlyFish.software at gmx.net
Fri Oct 15 17:57:54 CEST 2010
On Fri, 15 Oct 2010 16:45:04 +0200, Andrew Brunner
<andrew.t.brunner at gmail.com> wrote:
> It was also suggested that PThread's Suspend and Resume may not do
> anything. What I would do (if that is the case), is try to find where
> PThread has access to the Semaphore or CriticalSection it has on that
> thread...
Huh? Why should the pthreads library have a semaphore or similar on each
thread?
> IMO. You must assume that all variables of the TThread descendant have
> already been assigned and are valid.
Yes, but you can't. Even if you assign all values before calling the
inherited Create, there is a hidden function called "AfterConstruction"
which gets executed out of the threads context, so for instance the
thread id may not be set yet (actually, the thread id is returned
earliest when Execute gets called, so there's no way to retrieve it
*before*). If you access it inside the execute method, you more or
less crash (or at least leak memory).
It took me a couple of days to find the reason for our application
crashing and I believe that was fixed quite a while ago. (Somewhere
around 2.0.4, IIRC). Jonas may remember.
Excerpt from the workaround I had written then:
type
//-- @abstract(Thread class circumventing a race condition in thread
//-- creation present in the fpc 2.0.x tree.)
//-- The workaround works by starting the thread routine in suspended
//-- mode and waking it up after the constructor is known to have
//-- finished initializing all needed instance internals.
tThread = class (Classes.tThread)
public
{/= Create =====================================================\}
{ }
{\==============================================================/}
//-- @abstract(The usual thread constructor.)
//-- Overwritten to ensure it starts in suspended state, woken up
//-- by @link(AfterConstruction) a little moment later.
constructor Create;
{$IFDEF UNIX}
{/= Destroy ====================================================\}
{ }
{\==============================================================/}
//-- @abstract(Destroys the thread and does a "best effort" to
//-- avoid memory leaks by deciding if it should call
//-- pthread_detach or pthread_join (WaitFor).)
destructor Destroy; override;
{$ENDIF UNIX}
{/= AfterConstruction ==========================================\}
{ }
{\==============================================================/}
//-- @abstract(Resumes the suspended thread.)
//-- This ensures that the constructor completed before @code(
//-- Execute) is actually running.
procedure AfterConstruction; override;
end {tThread};
A similar workaround got into FPC a while later and it *was* for a
good reason: Safety.
> There is no need to block the thread from execution.
Actually there currently is. Otherwise you ask for trouble.
> That is unless they are asking to have it
> suspended on creation. And if that is the case... We need to tie into
> PThread's Semaphore or Event or CriticalSection and exploit that.
What do you want to tie into there?
Vinzent.
More information about the fpc-pascal
mailing list