ending thread

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Ozguxxx

ending thread

Post by Ozguxxx »

Hi, I am trying to figure out how an os understands when some thread is finished or not. (in other words, how can one thread enter into its terminal or ?zombie? state, I mean the mechanism.) Does thread finish itself? I think this is not the case because in programming theads under windows you dont call explicitly to kill thread. Or does os look if thread had reached its end? Also how can finishing threads return values? Some hints will really help. Thanx...
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:ending thread

Post by distantvoices »

Either you do it by signal handlers which in turn trigger some Exit registered with the process/thread. usually this is determined upon compile time - the OS registers p. ex. the standard exit with the process which means: quit the process gracefully - let it finish what ever it does and then let it vanish, which includes all the necessary cleanups.

You might have a field in the process structure which points to a set of OS functions which take care of signal handling and quitting/killing the process.

Furthermore, imagine what is done with a programm upon compile time:

first it gets compiled.

Then you link it with the standard runtime library.

At linking time, it gets a stub which jumps to the entry point of the program (jmp _main()) and passes possible argc,argv values to it. Then it gets some routines linked to AFTER void main() which are to be present: to call OS primitives which take care that the process vanishes in a proper way.

These are POSSIBLE ideas resulting of some quick brain dumping. Surely in some os book they are formulated clearer and nicer.

stay safe
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:ending thread

Post by Pype.Clicker »

in posix threads, you can terminate a thread either by an explicit call (something like pthread_terminate()) or by just returning from the thread's root function (simply because the pthreads library have actually called a function of its own as the real root which do

Code: Select all

{
    thread.root();
    thread_terminate();
}
It's pretty difficult to terminate threads, and especially kernel-mode threads.
::) oops . sorry for those who followed the link. seems i forgot to add this part to the document ::)
Ozguxxx

Re:ending thread

Post by Ozguxxx »

Well, I think this signaling approach is pretty impressive but I do not know much (in fact anything) about signaling stuff, can somebody show me resource to find info about signaling thing? I will be very appreciated if somebody tells briefly how this signaling works. Thanx...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:ending thread

Post by Pype.Clicker »

well, iirc, each process can register handlers for some signal (under unix, you have quite few signals available, something like 16 of them, and most have system-wide meaning like "SIGSEGV" or "SIGSTOP").

When a signal is sent to a process, the kernel sets a bit in the process structure. When the scheduler will dispatch this process, it will notice the signal bit is set and look out for the signal handler (rather than continuing the normal user code).
According to what the signal handler code performs, the handler may kill the process (this is the default case for CTRL+C or sigsegv, for instance), or ignore the signal (default for SIGUSR1) ... But one can re-program the handlers to make them perform the requested operation, like printing "timed out" when SIGALRM is raised...

Hope i didn't make too much mistakes :)
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:ending thread

Post by distantvoices »

hmmm ... i know this overriding of signal handlers from bs2000 mainframe: there, a programmer can replace the routines for STXIT (standard exit) by own ones which are linked to the program and executed by bs2000 in case a signal concerning the process in question arrives. thus one can avoid termination of a transaction-sensitive application by a user who by accident presses ctrl-3 (the same like ctrl-c).

So the scheduler calls the signal handler dependent on which bit in the signal-field of the process structure is set? So, a process can only receive one signal at a time. If I understand you right, Pipe, it is the task of scheduler to execute the signal-handling PRIOR to scheduling. This can cause the actual process vanish or be moved to some blocked-queue. Do I understand this right?
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Ozguxxx

Re:ending thread

Post by Ozguxxx »

OK, then about signaling approach: There must be some signal that is to be sent to kernel to say that "I am finished and dont schedule me anymore..." but this signal must be abstracted from thread's own code I mean I dont want to call to finish thread explicitly. Anyway, so the only way that this signal is sent is when multithreaded procedure RETurns, right? So This signaling is done when thread RETurns. Am I right? In that situation, upon creating thread, we simply make a copy of calling terminating function for this thread. (Setting correct parameters on which thread to kill.)When thread returns, it returns to this present(in compile time) function and this function tells scheduler that thread is done and it can be put into terminal state to be destroyed. But I think for doing all these things our stack should be correctly set (at thread creation) so that thread returns to correct position -to the function or to piece of code that kills it upon end of it- when finished. What do you think about this approach?
Ozguxxx

Re:ending thread

Post by Ozguxxx »

Hi, things started to make sense but I do not undestand why each thread needs different destroying signal handler, I mean cant we just kill each thread by just releasing memory that it uses and etc , in same way?
Curufir

Re:ending thread

Post by Curufir »

Ozguxxx wrote: Hi, things started to make sense but I do not undestand why each thread needs different destroying signal handler, I mean cant we just kill each thread by just releasing memory that it uses and etc , in same way?
Ok, consider this scenario:

I have one process, that spawns 3 threads (t1,t2,t3) and t1 spawns a further 3 threads (t1.1,t1.2,t1.3).

Let's say t2/t3/t1.1/t1.2/t1.3 ends. This situation is easily dealt with since they have no dependents, just release memory and kill the thread.

Now let's say t1 is killed while t1.1/t1.2/t1.3 are still running. What happens?

You need to be able to give well defined behaviour for this scenario (And all the other fun threading situations :)). Either all child threads are immediately killed on death of their parent (The safe way, but you risk data loss), child threads are permitted to divorce themselves from their parent and exist independently (Much more dangerous, but has its advantages), or the parent thread blocks waiting for all child threads to finish (Which keeps your data safe, but might not be the behaviour you want).

It's likely that you will want to apply a different protocol depending on the application/current situation. The way to do that is to keep track of threads independently, and in such a manner that you can signal associated threads (If required) when another one is killed.

It's a pity everyone uses the term thread. I've always thought lightweight process is a lot more descriptive.
Ozguxxx

Re:ending thread

Post by Ozguxxx »

OK, I understand your point but then think about this:

- A thread will be killed:
a) Check if it has childs and tell them their parent is to be killed. Does not bother child threads any more.
b) Check resources (files, ports, devices) currently used by this thread and get ready to close them.
c) ...
d) Release memory used by thread.

This scenario holds (I think for every thread), right? The dependent protocol takes its place when child threads communicate with os for returning immediately or not when their parent is killed. BTW lightweight processes might be correct word, I am not really aware of terminology so I use 'thread' for every task so if there are technical errors in my speaking, I am sorry. ;D
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:ending thread

Post by distantvoices »

@curufir: You are right as concerns the descriptiveness of "lightweight process". But "thread" shorter. *ggg*

@ozguxx: If you want to speak of full fledged processes with their own adress space, stack, heap, code ... just call them "processes". If you want to speak of some trhing that runs in the context of a process, shares code and data ... then speak of a "thread". It is just a suggestion, but it maybe eases communicating a problem. And I am sure that you'll sort things out.

You can keep this parent/child-process-bookkeeping scenario in mind, but if i were you, i won't overcomplicate things in the process management world.

One hint: which process siblings you kill depends on the dependencies: ipc & others. It makes no sense to kill all the httpd-processes because the parent process that spawned the others got killed. You just have to take care, that one of the others gets the shared code, and that depending on your design, one of the remnaining httpd siblings or the init-process becomes parent of the others.

stay safe
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
_mark

Re:ending thread

Post by _mark »

I'm not sure I agree with:
One hint: which process siblings you kill depends on the dependencies: ipc & others. It makes no sense to kill all the httpd-processes because the parent process that spawned the others got killed. You just have to take care, that one of the others gets the shared code, and that depending on your design, one of the remnaining httpd siblings or the init-process becomes parent of the others.
This not only would make shutting down a process and it's children very difficult, but under certain circumstances it may also requires the application be made aware that it is now the "parent". Take for instance, X Windows. When I shut down X, I want all my X apps to go away. I can however, shutdown the window manager and start a new one if I like, but the window manager does not own the apps as it's children. Or an even more basic example - what happens when you logout?

It is up to an application and it's children to repond correctly to a shutdown event, or SIGKILL or whatever you want to call it. If it does not repsond in a timly maner, then the rug is yanked from underneith it and all it little ones.

Just my 2 cents...
_mark
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:ending thread

Post by distantvoices »

@__mark(): You are indeed right, gosh:

an X application to run depends on a present X server which takes care of all these imaging and eventing agencies the application (the x client) does not have to take care of. So, if you kill the x server, the x clients have to die anyway due to non existent x server: no more communication - buffy the process killer is to come along (some os where i have seen read this *ggg*) because the x clients miss one critical condition: the presence of the x server.

you 'll encounter this when you try to start p.ex. xzoom without x say at runlevel 3. It will complain about missing display 0:0 (or similar) and die away.

but for ex. httpd & sigkill: does it make sense, when i have 10 httpd's lingering around busy with some requests and have to kill exactly the on which is the first in that "family", because it craps out due to some mischief, that all the others have to die away too?

I think this depends on the relations, the entities have together, how they have to react to signals. And in case of X_Server/X_Client I fully agree with you.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
_mark

Re:ending thread

Post by _mark »

I certainly would not design an http server in the maner you have described. If the requests are being serviced by inetd (which spawns httpd), then the discussion is somewhat moot, but if httpd handles port 80 all on it's own, then I would think a threaded model is a better approch. Let the main process take the request and then forward it on to a worker thread. That way if I want to shut down the server it is simple.
Apache on the other hand I think works in a similar manner as you have described, but I do not think it is the OS that handels the details - I'm pretty sure apache does that all on it's own.

I could be wrong...it would not be the first time...:)
_mark()
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:ending thread

Post by distantvoices »

It is as following:

inetd has the task to take an incoming signal and dispatch it to the other daemons lingering around: say a http request at port 80 comes in. you have 10 httpd-daemons waiting for work. inetd takes the first free one and hands the request over to it. then it takes the second one till all 10 are busy doing something. Only if there are more requests, it spawns some more httpd's (to the max. number of daemons indicated in httpd.conf) and gives them the request to handle them. After the work is done, the httpd-daemons remain idle. I don't know EXACTLY if the ones exceeding the number of ten die.

I think, each approach has its advantages and disadvantages.

a httpd daemon with multithreading would of course make sense ... but what happens when one thread craps out and the OS find's it is good to remove the whole context - the rag is teared away from bebeneath the full process and all the other requests are thrown away too. This is why I think, independent processes are a better solution.
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
Post Reply