Hi All,
I have a problem with dynamic creation and destruction of threads. It
seems it is not safe to call ThreadDestroy. The following little program
hangs on the last line:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <sys/neutrino.h>
void * func( void *arg )
{
delay(1);
printf(“Thread\n”);
return NULL;
}
int main( int argc, char* argv[] )
{
pthread_t thread;
if (pthread_create(&thread, NULL, &func, NULL) != EOK)
{
printf(“Failed to create.\n”);
}
delay(1);
if (ThreadDestroy(thread, -1, NULL) == -1)
{
printf(“Failed to destroy.\n”);
}
printf(“Destroyed the thread.\n”);
}
I guess it is a problem of killing the thread inside printf call. printf
is thread safe, nevertheless it doesn’t seem to be ThreadDestroy safe.
Is this a bug, a feature, or a misunderstanding ? May ThreadDestroy be
used at all with libc functions ?
Thanks for any advice.
Best regards
Lukas Kunc
Lukas Kunc <Lukas.Kunc@soft-gate.de> wrote:
if (ThreadDestroy(thread, -1, NULL) == -1)
I suspect that the last argument shouldn’t be NULL. Here’s what the
docs say this argument is:
The value to make available to a to a thread that joins a nondetached
thread that’s destroyed.
The docs for pthread_exit() – which calls ThreadDestroy() – say:
A pointer to a value that you want to be made available to any thread
joining the thread that you’re terminating.
Steve Reid stever@qnx.com
Technical Editor
QNX Software Systems
Steve Reid wrote:
Lukas Kunc <> Lukas.Kunc@soft-gate.de> > wrote:
if (ThreadDestroy(thread, -1, NULL) == -1)
ThreadDestroy() just causes the thread to disappear, without calling any
cancellation handlers. If the thread holds any mutexes when you destroy
it, they won’t be unlocked. In particular, if you destroy a thread
while it’s running printf(), you’re likely to leave stdout locked by a
non-existent thread, causing any other thread that calls printf() to
block indefinitely.
In short, a ThreadDestroy() call has pretty much the same result as
pthread_abort(). There are a few warnings and disclaimers on the
pthread_abort() page that also apply to ThreadDestroy() (and maybe
should be mentioned there, Steve!).
If you want a safer way to destroy a thread, use the POSIX
pthread_cancel() call. It will ensure that any cleanup handlers get
called before the thread disappears, which will leave the standard
library in a sane state. One caveat here is that by default, a thread
only notices a pending cancellation request during certain library calls
(check for functions flagged as “cancellation points”). You can change
the thread to be cancellable asynchronously, but it’s not safe for such
a thread to call most library functions (including printf()).
I suspect that the last argument shouldn’t be NULL. Here’s what the
docs say this argument is:
The value to make available to a to a thread that joins a nondetached
thread that’s destroyed.
The docs for pthread_exit() – which calls ThreadDestroy() – say:
A pointer to a value that you want to be made available to any thread
joining the thread that you’re terminating.
Steve Reid > stever@qnx.com
Technical Editor
QNX Software Systems
Thank you for reply. That’s what I thought, although I remember I read
an article which said, that when a thread terminates, all mutexes held
by the thread are released. Probably it was article about another OS.
Best regards
Lukas Kunc
Wojtek Lerch wrote:
Steve Reid wrote:
Lukas Kunc <> Lukas.Kunc@soft-gate.de> > wrote:
if (ThreadDestroy(thread, -1, NULL) == -1)
ThreadDestroy() just causes the thread to disappear, without calling any
cancellation handlers. If the thread holds any mutexes when you destroy
it, they won’t be unlocked. In particular, if you destroy a thread
while it’s running printf(), you’re likely to leave stdout locked by a
non-existent thread, causing any other thread that calls printf() to
block indefinitely.
In short, a ThreadDestroy() call has pretty much the same result as
pthread_abort(). There are a few warnings and disclaimers on the
pthread_abort() page that also apply to ThreadDestroy() (and maybe
should be mentioned there, Steve!).
If you want a safer way to destroy a thread, use the POSIX
pthread_cancel() call. It will ensure that any cleanup handlers get
called before the thread disappears, which will leave the standard
library in a sane state. One caveat here is that by default, a thread
only notices a pending cancellation request during certain library calls
(check for functions flagged as “cancellation points”). You can change
the thread to be cancellable asynchronously, but it’s not safe for such
a thread to call most library functions (including printf()).
I suspect that the last argument shouldn’t be NULL. Here’s what the
docs say this argument is:
The value to make available to a to a thread that joins a
nondetached thread that’s destroyed.
The docs for pthread_exit() – which calls ThreadDestroy() – say:
A pointer to a value that you want to be made available to any
thread joining the thread that you’re terminating.
Steve Reid > stever@qnx.com
Technical Editor
QNX Software Systems