When we are trying to ask current thread to join a thread A, the current thread will wait until the thread A terminates. If before the current thread invoke "join" to wait for thread A to terminate, the thread A has already been terminated. What will happen to the current thread? Deadlock or thread library implementation specific behavior?
thanks in advance,
George
manish_velankani
August 22nd, 2005, 12:28 AM
On using posix threads to test your scenario, I found that there is no deadlock in the state of current thread. Library internally checks for existence of thread id for which pthread_join has been called. If id does not exist then its imply moves ahead.
If the exit is called on parent thread while it is waiting for child using join then parent thread will terminate the wait without caring about child.
George2
August 22nd, 2005, 09:17 AM
Thanks manish_velankani,
On using posix threads to test your scenario, I found that there is no deadlock in the state of current thread. Library internally checks for existence of thread id for which pthread_join has been called. If id does not exist then its imply moves ahead.
Your reply is very helpful. I am wondering whether "Library internally checks for existence of thread id for which pthread_join has been called. If id does not exist then its imply moves ahead" is formally documented in any Linux thread specifications or standards.
regards,
George
Andreas Masur
August 22nd, 2005, 10:22 AM
[ Redirected thread ]
sszd
August 22nd, 2005, 10:42 AM
Unless a thread is started in a detached state, once it terminates its resources are still tied up until the thread is either joined by another thread or set detached by some other thread. This is why it is perfectly fine to join with a thread even after it has terminated. In fact, you had better join with it (or set it detached) if you don't want a resource leak.
The reason for a threads' resources to remain tied up after its termination is so some other thread can retrieve its return value(s) (i.e. the results of the terminated thread).
Note: Join is simply a convenience, not a necessity! You can retrieve a threads results by other means if it is more convenient for you to do so. Just remember, you must still make sure your threads' resources are cleaned up (by either detaching the thread at some point, or joining with it)!
Additional note: Once a threads resources have been cleaned up and freed, the thread id is available to be reused by the OS. So don't assume it's id is unique. If you do, you might accidentally be joining with the wrong thread if your code is written incorrectly.
George2
August 22nd, 2005, 10:25 PM
Thanks Andreas,
[ Redirected thread ]
I think this forum is more suitable for my topic. Thanks!!
regards,
George
George2
August 23rd, 2005, 08:21 AM
Thanks sszd,
Unless a thread is started in a detached state, once it terminates its resources are still tied up until the thread is either joined by another thread or set detached by some other thread. This is why it is perfectly fine to join with a thread even after it has terminated. In fact, you had better join with it (or set it detached) if you don't want a resource leak.
Your reply is very helpful. I do not quite understand about your above points.
1. How resource will leak if we do not use join?
2. How resource will not leak if we do use join?
Could you provide a simple sample to show them please (or where could I find a related sample)?
regards,
George
sszd
August 23rd, 2005, 02:25 PM
Thanks sszd,
Your reply is very helpful. I do not quite understand about your above points.
1. How resource will leak if we do not use join?
2. How resource will not leak if we do use join?
Could you provide a simple sample to show them please (or where could I find a related sample)?
regards,
George
Every time you start a thread there is a thread id assigned by the OS. There are only a limited number of id's available on a per-process level (this limit is configurable, however). Any value the thread may be trying to return may also be taking up resources (memory and so forth). Once a thread exits, it goes into what's known as a "Terminated" state (unless it was started in a detached state). It will stay in that state until another thread joins with it or sets it detached, at which point the thread (and it's resources) can then be "recycled" by the OS. Among other things, this also means the thread's id can be reused for another thread that may be created at some later time during the programs execution. So, unless the thread is recycled you will have a resource leak.
Note: A thread in a detached state will be recycled immediately upon exiting.
George2
August 24th, 2005, 12:45 AM
Thanks sszd,
Every time you start a thread there is a thread id assigned by the OS. There are only a limited number of id's available on a per-process level (this limit is configurable, however). Any value the thread may be trying to return may also be taking up resources (memory and so forth). Once a thread exits, it goes into what's known as a "Terminated" state (unless it was started in a detached state). It will stay in that state until another thread joins with it or sets it detached, at which point the thread (and it's resources) can then be "recycled" by the OS. Among other things, this also means the thread's id can be reused for another thread that may be created at some later time during the programs execution. So, unless the thread is recycled you will have a resource leak.
Note: A thread in a detached state will be recycled immediately upon exiting.
Your reply is very helpful. Suppose before we join a thread, the thread has already "terminated" (i.e. exit from thread entry point function), at this status, will join still help OS to do resource recycle (compared with the status when joining a thread, the thread has not been terminated yet)?
Every time you start a thread there is a thread id assigned by the OS. There are only a limited number of id's available on a per-process level (this limit is configurable, however). Any value the thread may be trying to return may also be taking up resources (memory and so forth).
You mentioned OS will help to recycle (reuse) the thread ID. I agree with this point. But I do not agree with your point about release other types of resources (such as memory as you mentioned). Suppose a thread allocates a buffer using malloc, do you mean calling join method to let current thread wait for the termination of the thread will help to release the buffer allocated using malloc?
regards,
George
sszd
August 24th, 2005, 11:26 AM
Suppose before we join a thread, the thread has already "terminated" (i.e. exit from thread entry point function), at this status, will join still help OS to do resource recycle (compared with the status when joining a thread, the thread has not been terminated yet)?
Yes. If the thread has already terminated, as I mentioned, it goes into a terminated state and waits to be joined with or be detached. If you join with a thread before it terminates, then when it finally terminates it will exit immediately from the terminated state and be recycled.
You mentioned OS will help to recycle (reuse) the thread ID. I agree with this point. But I do not agree with your point about release other types of resources (such as memory as you mentioned). Suppose a thread allocates a buffer using malloc, do you mean calling join method to let current thread wait for the termination of the thread will help to release the buffer allocated using malloc?
You are correct. I should have been a little more specific. When a thread is recycled all "system" resources are released. Any dynamically allocated resources ("program" resources) made by the thread (e.g. new, malloc, etc.) will not be released. They can, however, be released by any other thread if you happen to have the addresses.
George2
August 25th, 2005, 01:04 AM
Thanks sszd,
Yes. If the thread has already terminated, as I mentioned, it goes into a terminated state and waits to be joined with or be detached. If you join with a thread before it terminates, then when it finally terminates it will exit immediately from the terminated state and be recycled.
Your reply is very helpful. If we use current thread to join a thread after it exits its thead entry point method (i.e. after it has already terminated), the current thread will not be blocked (comparing with joining a thread before it terminates). Am I correct (I am not sure whether it is formally mentioned in any pthread specifications or standards)?
regards,
George
sszd
August 25th, 2005, 12:44 PM
If we use current thread to join a thread after it exits its thead entry point method (i.e. after it has already terminated), the current thread will not be blocked (comparing with joining a thread before it terminates). Am I correct (I am not sure whether it is formally mentioned in any pthread specifications or standards)?
That is not entirely true. The joining thread will block for an extremely short period of time (while the thread being joined with can proceed through its termination state and return any necessary value). In fact, the joined thread might even continue through and complete the recycling state before the calling thread returns from the join call. As a side note, this also means it is very important that the returned value is not a stack address associated with the terminated thread's stack.
I've not read the POSIX Thread specifications, however, I can't imaging such a thing being present since the OS is free to swap out threads at any given time. And other architectures with varying OS's may act completely different from previous observations. In fact, depending on what you are doing and how you are doing it, even your own system with the same program may return different results from one run to the next.
kempofighter
August 25th, 2005, 07:51 PM
Hello everyone,
When we are trying to ask current thread to join a thread A, the current thread will wait until the thread A terminates. If before the current thread invoke "join" to wait for thread A to terminate, the thread A has already been terminated. What will happen to the current thread? Deadlock or thread library implementation specific behavior?
The purpose of pthread_join is simply to recover resources from a terminated thread. So if the thread you are joining to is already terminated, there should be no problem. When you do a waitforsingleobject on a thread handle in windows, I believe the same thing is true. If the thread is already terminated, it's not a problem. No waiting has to be done. There is no deadlock problem here. In fact, I would never call pthread_join until I know the thread is terminated or at least has broken out of it's loop by sending the thread an event. Based on my understanding of the documentation, I feel that the safest way to rejoin is to use an event so that you can verify that the thread has broken out of it's loop prior to calling pthread_join. I would think that in most safe designs, the thread would be terminated or very close to terminating when pthread_join is invoked so that you don't risk deadlocking the system waiting for a thread to terminate that is stuck waiting for an event to occur.
In my thread designs, I'm normally working with a threadfunc that engages a loop that waits for events and loops (processing data within the loop) until it receives an event to shutdown. So I'd push a shutdown event and then design a verification that the thread has exited it's loop, possibly using a boolean class member or global variable or something like that prior to calling the pthread_join method.
That's my understanding but if someone has other info or documentation on pthread_join that contradicts this, I'd like to see it. I'm pretty new to the POSIX world myself.
The purpose of pthread_join is simply to recover resources from a terminated thread. So if the thread you are joining to is already terminated, there should be no problem. When you do a waitforsingleobject on a thread handle in windows, I believe the same thing is true. If the thread is already terminated, it's not a problem. No waiting has to be done. There is no deadlock problem here. In fact, I would never call pthread_join until I know the thread is terminated or at least has broken out of it's loop by sending the thread an event. Based on my understanding of the documentation, I feel that the safest way to rejoin is to use an event so that you can verify that the thread has broken out of it's loop prior to calling pthread_join. I would think that in most safe designs, the thread would be terminated or very close to terminating when pthread_join is invoked so that you don't risk deadlocking the system waiting for a thread to terminate that is stuck waiting for an event to occur.
In my thread designs, I'm normally working with a threadfunc that engages a loop that waits for events and loops (processing data within the loop) until it receives an event to shutdown. So I'd push a shutdown event and then design a verification that the thread has exited it's loop, possibly using a boolean class member or global variable or something like that prior to calling the pthread_join method.
That's my understanding but if someone has other info or documentation on pthread_join that contradicts this, I'd like to see it. I'm pretty new to the POSIX world myself.
Your reply is very helpful. As you mentioned, if I do not invoke pthread_join, resources will leak. I am also new to POSIX threads and I am very interested in this point. Do you know how can I verify the resources will leak if I do not invoke pthread_join? Simply by some Linux commands or have to write a simple program?
regards,
George
kempofighter
September 7th, 2005, 02:24 PM
Thanks kempofighter,
Your reply is very helpful. As you mentioned, if I do not invoke pthread_join, resources will leak. I am also new to POSIX threads and I am very interested in this point. Do you know how can I verify the resources will leak if I do not invoke pthread_join? Simply by some Linux commands or have to write a simple program?
regards,
George
With visual studio, the compiler will print out errors such as memory leaks when you shutdown the program. Since I do not really work with linux much, I can only assume that there is a useful compiler/debugger that will provide this information when your program shutsdown. Sorry for the late reply. I guess I forgot to subscribe to the thread and was not notified of a reply.
Unfortunately, I'm not much help on this issue as I am not familiar with linux compilers. memory leaks are tricky because many times they will happen and won't be a big deal. In one case, if you have a program that launches and stops many threads, eventually the system will run out of memory resources and start throwing exceptions or return errors when you try to use new or OS calls to create objects or new threads. Some cases, memory leaks happen only on shutdown because you forget to delete a couple of objects or to properly shutdown a thread as the program is exiting and cleaning up. These are the kinds of memory leaks that tend to go unnoticed unless you have a compiler / debugger warning you about them, or some kind of debugging helper tool that monitors these things. There are plugins that work with visual studio, for instance, that run as the program is running and will store detailed information about possible errors, memory leaks, as the program runs. Perhaps you could ask around and see if you can find a similar utility for whatever linux compiler you are working with.
George2
September 10th, 2005, 12:59 AM
Thanks kempofighter,
With visual studio, the compiler will print out errors such as memory leaks when you shutdown the program. Since I do not really work with linux much, I can only assume that there is a useful compiler/debugger that will provide this information when your program shutsdown. Sorry for the late reply. I guess I forgot to subscribe to the thread and was not notified of a reply.
Unfortunately, I'm not much help on this issue as I am not familiar with linux compilers. memory leaks are tricky because many times they will happen and won't be a big deal. In one case, if you have a program that launches and stops many threads, eventually the system will run out of memory resources and start throwing exceptions or return errors when you try to use new or OS calls to create objects or new threads. Some cases, memory leaks happen only on shutdown because you forget to delete a couple of objects or to properly shutdown a thread as the program is exiting and cleaning up. These are the kinds of memory leaks that tend to go unnoticed unless you have a compiler / debugger warning you about them, or some kind of debugging helper tool that monitors these things. There are plugins that work with visual studio, for instance, that run as the program is running and will store detailed information about possible errors, memory leaks, as the program runs. Perhaps you could ask around and see if you can find a similar utility for whatever linux compiler you are working with.
Your reply is very helpful. It seems that you are an expert of Visual Studio. If I have Visual Studio questions, I will ask you. ;)
have a good weekend,
George
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.