Re: pthread_join and pthread_detach
Re: pthread_join and pthread_detach
- Subject: Re: pthread_join and pthread_detach
- From: Paul Forgey <email@hidden>
- Date: Tue, 22 Mar 2005 12:42:24 -0800
What you are doing sounds frightening. Even if that did work, there's
no guarantee that pthread_join or pthread_detach ever reasonably expect
to work atomically if multiple threads potentially call it at the same
time on the same thread. Why do you need to do this? You can call
pthread_detach or pthread_join on an already exited thread, and if you
know ahead of time you will never need to join the thread, just create
it detached in the first place.
On the other hand, does your model really need to retain and release
reference counts to the thread? From the code you've quoted, no. Just
join on the thread from the first thread and be done with it. But if
there's more to it than that, consider something like this: Wrap your
thread handle around a structure containing a mutex and ref count, and
write functions to create, retain and release the thread appropriately.
struct MyThread
{
pthread_t thread;
pthread_mutex_t mutex;
int refCount;
};
On Mar 22, 2005, at 9:30 AM, email@hidden wrote:
Hi all,
in my app, some threads that cannot be detached a-priori : sometimes,
they
have to be joinable, but sometimes they can be detached (no other
thread
will wait for them).
At the same time, I needed to be sure that storage of all the thread
are
reclaimed when they terminate.
I set up a solution on Linux that ran properly.
On linux, I always detached the thread that may be joined JUST BEFORE
it
exists.
In case this thread was not awaited (no pending call to pthread_join()
by
another thread), its storage was reclaimed when terminating.
In case this thread was already awaited (joined) by another thread, the
pthread_join in the other thread resulted in a error EINVAL indicating
that the thread was detached. However, the storage was still reclaimed
when terminating, and the pthread_join exited when the joined thread
terminates (or just before). In a few words, it was 'OK'.
Here is an example of the code :
// THREAD 1 routine
// (thread 1 pthread_t is thread1_id)
void thread1_routine(void *data) {
// do some work
// wait for thread 2
// As an example, thread2 is here always joined.
// However, in my app, it is joined only in some cases
int res = pthread_join(thread2_id, NULL);
// in case the thread2 was not already terminated, EINVAL is
returned...
// in case the thread2 wa already terminated, ESRCH is returned...
if( res != 0) {
switch(res) {
case ESRCH :
printf("pthread_join error the thread is not valid\n");
break;
case EINVAL :
printf("the thread is already detached\n");
break;
case EDEADLK :
printf("called by the calling thread\n");
break;
default :
couterr <<"unknown"<<endl;
break;
}
}
}
// THREAD 2 routine
// (thread 2 pthread_t is thread2_id)
void thread2_routine(void *data) {
// do some work
// before terminating, detach the thread to be sure its storage is
reclaimed
int res = pthread_detach(thread2_id, NULL);
if( res != 0) {
switch(res) {
case ESRCH :
printf("the thread is not valid \n");
break;
case EINVAL :
printf("the thread is already detached\n);
break;
}
pthread_exit(NULL);
}
As far as I chercked, a code like this one does not run on mac os X.
The call to pthread_join results in :
mach_port_mod_refs(reply_port) failed: (os/kern) invalid name
mach_port_deallocate(kernel_thread) failed: (os/kern) invalid name
and sometimes in :
mach_port_deallocate(kernel_thread) failed: (os/kern) invalid name
*** malloc[1243]: Deallocation of a pointer not malloced: 0x580bc00;
This
could be a double free(), or free() called with the middle of an
allocated
block; Try setting environment variable MallocHelp to see tools to help
debug
(then, the program aborts).
Indeed, it seems that we cannot call pthread_detach on a thread while
this
thread is already by another thread awaited within a pthread_join.
Is that true ?
If it is, well... It is not documented in the man pages...
Does it correspond with the POSIX standard, or should I register it as
a
bug ?
Thx,
Nicolas
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden