Forum > General

Finishing thread does not release Virtual memory

<< < (5/5)

PascalDragon:

--- Quote from: jollytall on January 12, 2022, 10:06:22 am ---While we are at this point, a bit OFF spin-off question, that bothers me. It is always said (and indeed necessary) to put cmem and cthread to the top of the uses lists. I guess it is probably because their Initialization section does some initialization that is needed before other units start to initialize themselves. However I also thought that some of these special units redeclare some methods to provide extra functionality. The issue is that when two units have the same method then always the last one is used not the first. How is it managed for these special units, or they do not overwrite any existing method?
--- End quote ---

Those don't override any methods, but instead set the managers (TMemoryManager in case of cmem and TThreadManager in case of cthreads) which are in turn used by functions like GetMem or BeginThread.


--- Quote from: jollytall on January 12, 2022, 12:46:13 pm ---But it did not. It was worse. The pointer was really there and "in use". As many of you pointed out, although the thread was gone, it left behind its pointer and the allocated memory. If the pointer had pointed to the first byte of the block, Valgrind would report it as "still reachable", clearly indicating that something is not released.
To release it, not Waitfor but EndThread was needed. In the above example, placing EndThread between lines 12 and 13 does the trick, and all memory leak is gone.

--- End quote ---

Yes, one is supposed to use EndThread from the thread function. We should probably mention that in the documentation for BeginThread.

Jonas Maebe:

--- Quote ---
--- Quote from: Jonas Maebe on January 12, 2022, 08:18:22 am ---We indeed don't have the functional equivalent for detaching a thread with the procedural interface. However, just to make sure, are you calling waitforthreadterminate on all of (non-detached) your threads? Otherwise they will indeed linger on forever.

--- End quote ---
Where shall I put it?

--- End quote ---

You can put it wherever you want. You have to store the result from BeginThread in a TThreadID variable (e.g. an array of TThreadID), and then use WaitForThreadTerminate with those TThreadID values as parameter to reap the threads after they are finished. WaitForThreadTerminate is a blocking call (i.e., if the thread hasn't ended yet, the call will keep waiting until it does), but you can pass a timeout if you want.


--- Quote ---Will it stop this leak?

--- End quote ---
It will definitely fix a leak you have when not doing this.

jollytall:
@Jonas,
I still do not understand this logic.

The one written above is clear. A Thread is started and when it finishes its activity, as a last step after it released all user allocated resources, it also releases the thread management allocated resources with an EndThread call.

What would be the purpose of WaitForThreadTerminate in this setup?
Surely, it would give an assurance to the caller (typically the main thread) that all threads finished their activity (e.g. closed all files they opened) and it is save to stop the whole process. This is important once in the lifetime of the program, at the very end.
Does it also make sure, that when the thread is terminated (joined) its resources are also freed? Reading the source code, it seems (without lengthy analysis) that it only calls the pthread_join system call and in the manual of pthread_join I do not see any resource de-allocation. This would probably not even be possible (I am not sure!), since a terminated thread might still have resources allocated and managed later by the thread it joined to.
Also, it would not be practical to have either the main thread blocked during the normal operation of the program (i.e. not at the very end) to see when a thread terminates (hundreds of threads with various running lengths), or to make a separate "thread managing thread" :).
As written above, the EndThread does the trick perfectly, without any blocking operation in the main thread. (And yes, I have a separate mechanism to wait for all the threads at the very end of the run of the program, not to kill them in the middle of their operation, but that is another topic).

Last to note, it is always a blocking operation on *nix operating systems; pthread_join has no timeout parameter.

Jonas Maebe:


--- Quote from: jollytall on January 13, 2022, 08:29:05 am ---@Jonas,
I still do not understand this logic.

The one written above is clear. A Thread is started and when it finishes its activity, as a last step after it released all user allocated resources, it also releases the thread management allocated resources with an EndThread call.

What would be the purpose of WaitForThreadTerminate in this setup?

--- End quote ---
Mainly synchronisation between the main thread and the child thread. Additionally, pthread_exit can return a value which can be captured by pthread_join (which is used by the FPC RTL to return the value passed to EndThread to WaitForThreadTerminate). This means the thread must keep state until WaitForThreadTerminate/pthread_join is called.


--- Quote ---Does it also make sure, that when the thread is terminated (joined) its resources are also freed? Reading the source code, it seems (without lengthy analysis) that it only calls the pthread_join system call and in the manual of pthread_join I do not see any resource de-allocation. This would probably not even be possible (I am not sure!), since a terminated thread might still have resources allocated and managed later by the thread it joined to.
Also, it would not be practical to have either the main thread blocked during the normal operation of the program (i.e. not at the very end) to see when a thread terminates (hundreds of threads with various running lengths), or to make a separate "thread managing thread" :).
As written above, the EndThread does the trick perfectly, without any blocking operation in the main thread. (And yes, I have a separate mechanism to wait for all the threads at the very end of the run of the program, not to kill them in the middle of their operation, but that is another topic).

--- End quote ---
It's simply how OS threading interfaces work on either Windows or Unix. This is not an FPC design. And yes, the OS/threading library keeps state around until you join a thread, unless it's a detached one. If you don't care for synchronisation with your threads for whatever reason, you need a detached threads. However, this functionality is indeed not exposed by the procedural FPC threading interface, because it's the exception rather than the rule in most programs.


--- Quote ---Last to note, it is always a blocking operation on *nix operating systems; pthread_join has no timeout parameter.

--- End quote ---
Indeed, I forgot about that.

Navigation

[0] Message Index

[*] Previous page

Go to full version