#include <threads.h>
void call_once( once_flag * flag, void (* function)(void) );
La fonction call_once
permet de lancer un appel à une autre fonction, mais à la condition que celle-ci n'ait pas déjà été invoquée.
Les demandes d'appels suivantes seront ignorées.
Pour savoir si la méthode a déjà été appelée, call_once
utilise une structure de données de type once_flag
.
Cette structure de données doit être initialisée à la valeur ONCE_FLAG_INIT
.
L'accès à cette structure de données par la fonction call_once
est bien entendu synchronisé contre les accès concurrents.
La fonction call_once
ne permet de contrôler l'appel que des fonctions respectant la signature suivante : void fctName();
.
flag : une structure de données permettant de savoir si la méthode à déjà été invoquée.
function : un pointeur sur la fonction à exécuter qu'une seule est unique fois.
La fonction call_once
ne renvoie rien.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include <stdio.h> #include <stdlib.h> #include <threads.h> #define THREAD_COUNT 4 // Une fonction qui ne doit pas être invoquée plus qu'une unique fois. void doOnlyOnceTime(void) { printf( "Cette fonction est invoquée qu'une unique fois !\n" ); } // Définition de la fonction sur laquelle amorcer tous nos threads. int threadFuntion(void* data) { // Une variable locale statique est une variable dont la durée de vie // est l'application mais qui n'est accessible que dans cette fonction. static once_flag flag = ONCE_FLAG_INIT; long index = (long) data; printf( "Thread %ld démarré.\n", index ); // Appel sécurisé à la fonction call_once( &flag, doOnlyOnceTime ); return thrd_success; } int main() { // On démarre tous nos threads sur la fonction définie ci-dessus. thrd_t threads[THREAD_COUNT]; for( long i=0; i<THREAD_COUNT; i++ ) { thrd_create( &threads[i], threadFuntion, (long *)i ); } // On attend la terminaison de tous nos threads. for( int i=0; i<THREAD_COUNT; i++ ) { thrd_join( threads[i], NULL ); } return EXIT_SUCCESS; } |
Pour compiler cet exemple sous environnement Linux/Unix, il est nécessaire de lier la librairie pthread (Posix Thread) à votre exécutable. Voici un exemple de compilation.
$> gcc -o sample sample.c -lpthread $>
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :