2010-08-24 7 views
2

J'ai écrit une bibliothèque basée sur C et pour qu'elle fonctionne en multi-thread parallèlement, je crée des mutex globaux dans la fonction init.Comment protéger la fonction init d'une bibliothèque basée sur C?

Je m'attends à ce que la fonction init soit appelée dans le thread principal avant que les API de bibliothèque ne soient utilisées dans le multi-thread. Mais, si la fonction init elle-même est appelée directement dans le multithread, alors c'est un problème. Y at-il un moyen de protéger la fonction init elle-même de ma bibliothèque? Une façon que je peux penser est de demander à l'application de créer un mutex et de protéger les appels parallèles à ma fonction init, mais puis-je le protéger de ma bibliothèque elle-même?

Répondre

5

Vous souhaitez probablement utiliser les fonctions de point d'entrée par défaut.

Dans Windows, vous pouvez utiliser DllMain pour créer et détruire vos mutex.

Sous Linux et probablement d'autres Unix, vous pouvez utiliser __attribute__((constructor)) et __attribute__((destructor)) pour vos fonctions d'entrée et de sortie.

Dans ces deux cas, les fonctions seront appelés une fois la charge et déchargent

+0

Peut-on les utiliser seulement avec dlopen ou cela fonctionnera-t-il même si on lie la bibliothèque dynamique en utilisant l'option -l à l'application? – Jay

+0

Cela semble être l'option spécifique de GCC. J'ai une application dans laquelle la bibliothèque sera liée en utilisant l'option -l et la même bibliothèque sera chargée en utilisant aussi dlopen. Que va-t-il se passer dans ce cas? Le constructeur sera-t-il appelé deux fois? – Jay

+0

Je pense que la réponse est oui. Constructeur et Destructeur fonctionnent également pour les exécutables standard. Voir http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Function-Attributes.html#Function-Attributes – doron

2

Posix a la fonction pthread_once

int pthread_once(pthread_once_t *once_control, 
       void (*init_routine)(void)); 

Dans la page de manuel linux, ils ont alors l'exemple instructif suivant

static pthread_once_t random_is_initialized = PTHREAD_ONCE_INIT; 
extern int initialize_random(); 

int random_function() 
{ 
(void) pthread_once(&random_is_initialized, initialize_random); 
       ... /* Operations performed after initialization. */ 
} 
Questions connexes