Threads - Self Terminating?
Threads - Self Terminating?
Win98 - If a thread-based procedure completes it's task and exits normally (or via a ProcedureReturn) shouldn't the thread itself be deleted? I'm talking about the thread/s as reported by a process monitoring utility. As far as PB is concerned everything appears ok but if your prog keeps launching threads then the number of threads reported by the system just keeps increasing. They *do* get cleaned out when the prog exits but this is no good for a prog that is intended to run continuously. I'm trying to avoid KillThread.
...,
Threads do not close alone, and you have to be careful to clean by yourself if you write a prog running threads, otherwise it may be some memory not freed.
Depending on the application you have, it is also possible that you run many threads in a high number so that the processor may hang because of priority management issues.
Rgrds
Threads do not close alone, and you have to be careful to clean by yourself if you write a prog running threads, otherwise it may be some memory not freed.
Depending on the application you have, it is also possible that you run many threads in a high number so that the processor may hang because of priority management issues.
Rgrds
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
... it should be !
I have noticed that it is not so sure.
When running an app using threads, if you use strings, which is a well known problem, I have had some head ache because the main program may end before threads are really terminated. I don't know how to make it really stable.
So, you have to register all threads you run, and manage your app so that you are sure what runs, and what ends, keeping the control in the main code.
I use to register by using either a linked list or an array, keeping the thread's ID until it ends. When a given thread ends, it cancels its instance in the array, so that the main code can know, what still runs or not.
And so on ...
I have noticed that it is not so sure.
When running an app using threads, if you use strings, which is a well known problem, I have had some head ache because the main program may end before threads are really terminated. I don't know how to make it really stable.
So, you have to register all threads you run, and manage your app so that you are sure what runs, and what ends, keeping the control in the main code.
I use to register by using either a linked list or an array, keeping the thread's ID until it ends. When a given thread ends, it cancels its instance in the array, so that the main code can know, what still runs or not.
And so on ...
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
My threads avoid strings and only do the bare minimum required. Everything else is done in main code (I try hard to minimise headaches
).
I'm not being lazy here, of course I have tried various things but I have noticed that getting something to work doesn't mean that it will work over an extended period, eg, that 1/1000000 chance of a hick-up that causes your code to hang
Anyway, thanks again.
I'm not being lazy here, of course I have tried various things but I have noticed that getting something to work doesn't mean that it will work over an extended period, eg, that 1/1000000 chance of a hick-up that causes your code to hang
Here's some code which shows my problem. No matter what I try the threads remain until the program (compiled on PB v3.81) actually quits. Any/all suggestions appreciated.
Code: Select all
; Monitored using: Process Explorer v8.20 (www.sysinternals.com)
Global n.l, q.l ; (n)umber of threads to run, (q)uit flag
Dim tid.l(10) ; Thread ID's
Dim tff.l(10) ; Thread Finished Flags
Procedure dumdedum(d.l)
Shared q.l
Delay(d): q=1 ; Delay then set quit flag
EndProcedure
Procedure athread(tn.l)
Delay(2000+Random(3)*1000) ; 2..5 secs delay
tff(tn)=1 ; Finished Flag
;KillThread(tid(n))
EndProcedure
; Start some threads
n=3 ; Number of threads to start
For i=1 To n: tid(i)=CreateThread(@athread(),i): Next
CreateThread(@dumdedum(),10000) ; WatchDog thread
; Monitor threads...
Repeat
Delay(500)
c=0
For i=1 To n
If tff(i)=1: c+1: EndIf
Next
If q: Debug "time-out": Break: EndIf
If c=n: Debug "all-finished": Break: EndIf
ForEver
Debug "Still see the threads? 4 secs to check!"
Delay(4000) ; 4 sec while you check
; Now try explicit kill/ terminate...
For i=1 To n: If tid(i): KillThread(tid(i)): EndIf : Next
Debug "How about now? 4 secs to check!"
Delay(4000) ; 4 sec while you check
For i=1 To n: If tid(i): TerminateThread_(tid(i),0): EndIf : Next
Debug "Don't tell me they are still there!? 4 secs to check!"
Delay(4000) ; 4 sec while you check
End
dmoc,
This is the way I would do :
Seems to work ... tell me about results with this code on your side.
Rgrds
This is the way I would do :
Code: Select all
#NThreads = 10
Dim ThreadIDs.l(#NThreads)
Procedure athread(ThisThreadID.l)
Delay(2000+Random(3)*1000)
ThreadIDs(ThisThreadID) = 0
EndProcedure
Procedure.l WatchThreads()
Remains.l = 0
For i.l = 1 To #NThreads
If ThreadIDs(i) <> 0
Remains + 1
EndIf
Next
ProcedureReturn Remains
EndProcedure
n= 10 ; Number of threads to start
For i=1 To #NThreads
ThreadIDs(i)=CreateThread(@athread(),i)
Next
Repeat
Remaining.l = WatchThreads()
Debug "@ " + FormatDate("%hh:%ii:%ss", Date()) + " remains " + Str(Remaining) + " threads"
Delay(1000)
Until Remaining = 0
End
Rgrds
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
Ah, maybe I haven't explained myself clearly: as far as PB code is concerned the threads have terminated, at least as far as you can tell from monitoring your own state vars, but using a process monitor utility (like SysInternal's "Process Explorer") the threads are definately still listed in the process table (or whatever). To see this add a delay to the end of the program to give you time to switch to the process monitor. If a program really is terminating then it's not a problem but my program is continually firing one-shot threads which when exited/ killed/ terminated *still* remain. So the thread count according to system resources just continues increasing! See my problem?
I don't know really the way to ensure which is right and which is wrong.
By experience, I know that threads are really ended if the internal app monitoring tells so. And the allocated emory is freed also.
Using an external monitor does not give me more reults than what I see on the task manager.
When I did real tests, I was playing with usually 200- 1.000 threads for networking stuff, and I am sure whether threads release or not.
Well, ... can't tell more.
By experience, I know that threads are really ended if the internal app monitoring tells so. And the allocated emory is freed also.
Using an external monitor does not give me more reults than what I see on the task manager.
When I did real tests, I was playing with usually 200- 1.000 threads for networking stuff, and I am sure whether threads release or not.
Well, ... can't tell more.
My avatar is a small copy of the 4x1.8m image I created and exposed at 'Le salon international du meuble à Paris' january 2004 in Matt Sindall's 'Shades' designers exhibition. The original laminated print was designed using a 150 dpi printout.
Thanks for your help anyway. I did a google and came up with the following page...
viewtopic.php?t=6146&view=next
...yeah, right back here (funny I couldn't see it when I searched the forums). Turns out that "CloseHandle_(tid(i))" is preferable to other commands. I tried it and it seemed to do the job. I say "seemed" because with my quick test one or two threads were left over. Tomorrow I'm going to test with more threads and and see how it performs.
viewtopic.php?t=6146&view=next
...yeah, right back here (funny I couldn't see it when I searched the forums). Turns out that "CloseHandle_(tid(i))" is preferable to other commands. I tried it and it seemed to do the job. I say "seemed" because with my quick test one or two threads were left over. Tomorrow I'm going to test with more threads and and see how it performs.
Silly me, forgot about the stuff detailed near the end of this MS page...
http://msdn.microsoft.com/library/defau ... hreads.asp
...although I did think PB handled this itself.
http://msdn.microsoft.com/library/defau ... hreads.asp
...although I did think PB handled this itself.
-
PolyVector
- Enthusiast

- Posts: 499
- Joined: Wed Sep 17, 2003 9:17 pm
- Location: Southern California
- Contact:
I do this sorta thing
Or you could use my ThreadSync library... 
Code: Select all
Global QuitEvent.l
QuitEvent=CreateEvent_(#Null,#True,#False,"MyQuitEvent")
Procedure ThreadProc(x)
Repeat
Debug x
Until WaitForSingleObject_(QuitEvent,0)=0
Debug "Exit>"+Str(x)
EndProcedure
Dim hThread(10)
For x=1 To 10
hThread(x)=CreateThread(@ThreadProc(),x)
Next
Delay(1000)
SetEvent_(QuitEvent)
For x=1 To 10
WaitThread(hThread(x))
Next
Debug "All Threads Finished..."
PolyVector, I like your library but my only problem is getting rid of them once they are finished (with the prog still running, as it should be). I found the reason and it's because win98 still maintains an entry for a finished thread so it's exit code can be queried. Once all handles to a particular thread are freed then even this disappears. I don't think PB closes thread handles until the program itself exits.
fweil, update soon
fweil, update soon
I've tried it a number of times with a varying number of threads and CloseHandle_() seems to reliably purge thread leftovers. So I'm a happy chappy
But of course one thing leads to another and I wonder now how you can tell if a thread is still alive without keeping your own flags. Seems a reasonable request so I looked for a win32 function and can't find one. The nearest I see is GetThreadTimes_() but the key bit of info "lpExitTime" (a FILETIME structure) is undefined if the thread has not exited :roll: You'd think it would at least be a null ptr. Not to worry though, it's not a problem for me.