Re: C++ Function Static Initialization, Thread-Safe?
- From: Anthony Williams <anthony.ajw@xxxxxxxxx>
- Date: Wed, 30 Jul 2008 21:26:47 +0100
"Chris M. Thomasson" <no@xxxxxxxxxxxx> writes:
Here is a program that illustrates the problem nicely:
__________________________________________________________________
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
static pthread_once_t g_once = PTHREAD_ONCE_INIT;
static pthread_mutex_t g_mtx = PTHREAD_MUTEX_INITIALIZER;
static sem_t g_in_init;
void init(void) {
sem_post(&g_in_init);
puts("Thread waiting in init routine for `g_mtx'...");
pthread_mutex_lock(&g_mtx);
pthread_mutex_unlock(&g_mtx);
}
void* thread(void* state) {
pthread_once(&g_once, init);
return 0;
}
int main() {
pthread_t tid;
sem_init(&g_in_init, 0, 0);
pthread_mutex_lock(&g_mtx);
puts("Main thread has `g_mtx'...");
pthread_create(&tid, NULL, thread, NULL);
sem_wait(&g_in_init);
puts("Main thread waiting for init routine to finish...");
pthread_once(&g_once, init);
pthread_mutex_unlock(&g_mtx);
pthread_join(tid, NULL);
sem_destroy(&g_in_init);
return 0;
}
__________________________________________________________________
OUCH! There is no way around this. Your 100% correct that the
semantics need to be worked out. Perhaps there should be a guideline
that says you cannot take a mutex in the `init()' routine. Or perhaps
you cannot hold a mutex during a call to `pthread_once()'. This would
translate to C++ in that you cannot take a mutex in the ctor of an
object that may be used as a singleton. Or you cannot hold a mutex
before you make a call into the `instance()' function of a singleton.
Yes, this will deadlock. It's just a problem of waiting for something
whilst holding a lock, if the thing you are waiting for might need to
acquire the lock you hold.
The same applies with mutexes in general --- don't acquire a second
mutex whilst holding one in case another thread tries to acquire them
in the opposite order. It also applies to joining threads --- don't
join a thread whilst holding a mutex if that thread could try and
acquire the mutex.
I think I'd go for not acquiring locks in the once routine, as you
shouldn't need them too often, but IMHO the general guideline is
enough.
Anthony
--
Anthony Williams | Just Software Solutions Ltd
Custom Software Development | http://www.justsoftwaresolutions.co.uk
Registered in England, Company Number 5478976.
Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL
.
- References:
- C++ Function Static Initialization, Thread-Safe?
- From: Brian Cole
- Re: C++ Function Static Initialization, Thread-Safe?
- From: David Schwartz
- Re: C++ Function Static Initialization, Thread-Safe?
- From: Chris Thomasson
- Re: C++ Function Static Initialization, Thread-Safe?
- From: Chris Thomasson
- Re: C++ Function Static Initialization, Thread-Safe?
- From: David Schwartz
- Re: C++ Function Static Initialization, Thread-Safe?
- From: Chris M. Thomasson
- Re: C++ Function Static Initialization, Thread-Safe?
- From: Chris M. Thomasson
- Re: C++ Function Static Initialization, Thread-Safe?
- From: Chris M. Thomasson
- C++ Function Static Initialization, Thread-Safe?
- Prev by Date: Re: C++ Function Static Initialization, Thread-Safe?
- Next by Date: Re: C++ Function Static Initialization, Thread-Safe?
- Previous by thread: Re: C++ Function Static Initialization, Thread-Safe?
- Next by thread: Re: C++ Function Static Initialization, Thread-Safe?
- Index(es):
Relevant Pages
|