IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

POSIX C Discussion :

[GCC pthread_create avec en argument une fonction de callback parametré]


Sujet :

POSIX C

  1. #1
    Débutant
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    janvier 2004
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : janvier 2004
    Messages : 452
    Points : 324
    Points
    324
    Par défaut [GCC pthread_create avec en argument une fonction de callback parametré]
    Bonsoir à tous,

    Je souhaiterai créer un thread qui recoit en paramètre d'entrée une fonction de callBack qui elle aussi possède un paramètre.

    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int startProg(int num, PVOID fcCallBack(PVOID stat)
    {
       int status = 0;
     
       status = pthread_create( &threadOne, NULL, threadPrincipale, PVOID fcCallBack);
    Mon problème je pense, c'est que je lui passe deja comme argument le pointeur sur la fonction de callback, mais comment lui ajouter son propre argument (PVOID stat) ?


    voila la fonction threadPrincipale

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    PVOID threadPrincipale( PVOID fcCallBack(PVOID number))
    {
         int * r = number;
     
         printf("le numéro maitre vaut %d\n", *r);
     
         return null;
    }
    J'ai un message à ce moment la me disant :
    "Erreur "number" non déclaré (première utilisation dans cette fonction)"

    et voici mon programme principale avec le callback mentionné:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
     
     
    PVOID callBackNumber(PVOID num)
    {
         int * n = num;
     
         // .....
     
        return NULL;
    }
     
     
    int main(void)
    {
        int status = 0;
     
        status = startProg(0, (PVOID) CallBackNumber);
     
        // .....................;
     
        return 0;
    }
    Je sais que ca fait pas mal d'imbrications, mais elles sont nécéssaires dans le cadre de mon projet.

    Si quelqu'un pouvais me confirmer que c'est possible, je pourrais me débrouiller de mon coté, sinon comment procéder pour contourner mon problème ?

    J'espere avoir été assez claire.

    En tout cas Merci d'avance pour votre aide.

  2. #2
    Membre régulier Avatar de krieg
    Profil pro
    Inscrit en
    janvier 2009
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : janvier 2009
    Messages : 75
    Points : 92
    Points
    92
    Par défaut
    Salut,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    PVOID threadPrincipale( PVOID fcCallBack(PVOID number))
    {
         int * r = number;
     
         printf("le numéro maitre vaut %d\n", *r);
     
         return null;
    }
    Il est normal que number ne soit pas définie, le parametre
    de ta fonction, c'est la fonction fcCallBack.
    D'ailleur le passage d'une fonction en parametre ne se réalise pas comme ça.
    Je ne sais plus comme ça cela demande une petite
    recherche.
    bye

  3. #3
    Débutant
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    janvier 2004
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : janvier 2004
    Messages : 452
    Points : 324
    Points
    324
    Par défaut
    Citation Envoyé par krieg Voir le message
    Salut,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    PVOID threadPrincipale( PVOID fcCallBack(PVOID number))
    {
         int * r = number;
     
         printf("le numéro maitre vaut %d\n", *r);
     
         return null;
    }
    Il est normal que number ne soit pas définie, le parametre
    de ta fonction, c'est la fonction fcCallBack.
    D'ailleur le passage d'une fonction en parametre ne se réalise pas comme ça.
    Je ne sais plus comme ça cela demande une petite
    recherche.
    bye
    ah bon pourtant je vois pas d'autre moyen de la déclarer , ca fait deja un moment que je cherche et pas l'ombre d'un exemple

    sauf peu etre des parenthese , je vois vraiment pas ......

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     PVOID threadPrincipale( PVOID (fcCallBack(PVOID number)))
    en tout cas merci Krieg pour ta réponse, je continurerai à chercher demain

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    27 216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 27 216
    Points : 40 907
    Points
    40 907
    Par défaut
    Explique un peu plus ce que tu veux faire, s'il te plait.
    On a pas mal de noms de fonctions, mais on ne sait pas qui est supposé appeler quoi...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    27 216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 27 216
    Points : 40 907
    Points
    40 907
    Par défaut
    Typiquement, on fait ainsi:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    struct ma_struct_thread
    {
    	intptr_t (*ptrFonction)(int, double);
    	intptr_t ret;
    	int param1;
    	double param2;
    };
     
    PVOID MaFonctionThread(PVOID param)
    {
    	struct ma_struct_thread * pStruct = param;
     
    	pStruct->ret = pStruct->ptrFonction(pStruct->param1, pStruct->param2);
     
    	return NULL;
    }
     
    intptr_t MaCallback(int param1, double param2);
     
    int main(void)
    {
    	pthread_t thread;
    	struct ma_struct_thread stThread = { MaCallback, 0, 10, 42.0 };
    	int res = pthread_create(&thread, NULL, MaFonctionThread, &stThread);
    	if(res == 0)
    	{
    		puts("Lancement du thread OK.");
    		puts("Attente...");
    		pthread_join(thread, NULL);
    		puts("Fin.");
    		printf("Valeur de retour: %llx\n", (unsigned long long)stThread.ret);
    	}
    	else
    	{
    		printf("Error : %d\n", res);
    	}
    	return 0;
    }

    Bien sûr, ce code implique que la structure ait une durée de vie supérieure à celle du thread. On peut faire autrement avec l'allocation dynamique...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Débutant
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    janvier 2004
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : janvier 2004
    Messages : 452
    Points : 324
    Points
    324
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Typiquement, on fait ainsi:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    struct ma_struct_thread
    {
    	intptr_t (*ptrFonction)(int, double);
    	intptr_t ret;
    	int param1;
    	double param2;
    };
     
    PVOID MaFonctionThread(PVOID param)
    {
    	struct ma_struct_thread * pStruct = param;
     
    	pStruct->ret = pStruct->ptrFonction(pStruct->param1, pStruct->param2);
     
    	return NULL;
    }
     
    intptr_t MaCallback(int param1, double param2);
     
    int main(void)
    {
    	pthread_t thread;
    	struct ma_struct_thread stThread = { MaCallback, 0, 10, 42.0 };
    	int res = pthread_create(&thread, NULL, MaFonctionThread, &stThread);
    	if(res == 0)
    	{
    		puts("Lancement du thread OK.");
    		puts("Attente...");
    		pthread_join(thread, NULL);
    		puts("Fin.");
    		printf("Valeur de retour: %llx\n", (unsigned long long)stThread.ret);
    	}
    	else
    	{
    		printf("Error : %d\n", res);
    	}
    	return 0;
    }

    Bien sûr, ce code implique que la structure ait une durée de vie supérieure à celle du thread. On peut faire autrement avec l'allocation dynamique...
    Merci Médinoc, c'est bien ce que j'ai fais, en faites on m'a suggeré de faire passer une structure contenant ma fonction de callBack ainsi que ces paramètres.

    Mais justement ta dernière phrase m'intrigue :
    ce code implique que la structure ait une durée de vie supérieure à celle du thread

    Pourrais-tu etre un peu plus explicite, je vois pas trés bien ce que tu veux dire.

    En tout cas merci beaucoup pour ta réponse.
    En plus donnée avec un bon ptit exemple clair et net qui pourrais peu etre avoir sa place dans la FAQ pour les personnes qui rencontreront le meme problème.

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    27 216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 27 216
    Points : 40 907
    Points
    40 907
    Par défaut
    Citation Envoyé par moulefrite Voir le message
    Mais justement ta dernière phrase m'intrigue :
    ce code implique que la structure ait une durée de vie supérieure à celle du thread

    Pourrais-tu etre un peu plus explicite, je vois pas trés bien ce que tu veux dire.
    En clair: La structure est détruite après le pthread_join(), pas avant.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Débutant
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    janvier 2004
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : janvier 2004
    Messages : 452
    Points : 324
    Points
    324
    Par défaut
    Merci pour tes précisions,
    Dans mon cas, j'utilise une structure declaré en local contenant mon pointeur de fonction, et une structure globale, contenant son résultat.

    Ce qui me choque, c'est qu'au bout d'un certain nombre d'execution, j'ai une "erreur de segmentation", je pensait que c'etait lié à ce que tu viens de me dire, mais en faites non.

    La seule différence avec ton code, ce situe sur le pthread_join, moi je passe par un pthread_cancel, puis pthread_kill.

  9. #9
    Membre régulier Avatar de krieg
    Profil pro
    Inscrit en
    janvier 2009
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : janvier 2009
    Messages : 75
    Points : 92
    Points
    92
    Par défaut
    Salut,
    pour ton segmentation fault, utilse gdb tu sauras directement la ligne et la variable qui amène le segmentation fault.
    teste tu les valeur de retour des appels systèmes. tu as peux etre une création
    de threads qui retourne -1.
    bye

  10. #10
    Débutant
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    janvier 2004
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : janvier 2004
    Messages : 452
    Points : 324
    Points
    324
    Par défaut
    Citation Envoyé par krieg Voir le message
    Salut,
    pour ton segmentation fault, utilse gdb tu sauras directement la ligne et la variable qui amène le segmentation fault.
    teste tu les valeur de retour des appels systèmes. tu as peux etre une création
    de threads qui retourne -1.
    bye
    Merci Krieg pour ton astuce, mon erreur de segmentation proviens de l'écrasement de la zone mémoire contenant l'adresse pointant sur ma fonction de callback.

    Je suis en train de chercher un moyen qui va me permettre d'allouer une zone mémoire static sur ma fonction de callback.
    Mais bon pour l'instant rien de bien concluant.

  11. #11
    Membre régulier Avatar de krieg
    Profil pro
    Inscrit en
    janvier 2009
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : janvier 2009
    Messages : 75
    Points : 92
    Points
    92
    Par défaut
    Salut,
    je ne pense pas que ce soit la bonne solution, je pense qu'il faut trouver d'où viens ton écrasement mémoire. Tu peux tenter avec un watch sur l'adresse
    memoire avec gdb.
    il y a quelque chose de bizard dans ton code si tu passe par une autre
    méthode tu retrouvera une erreur bizard ailleur.
    bye,

  12. #12
    Débutant
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    janvier 2004
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : janvier 2004
    Messages : 452
    Points : 324
    Points
    324
    Par défaut
    Citation Envoyé par krieg Voir le message
    Salut,
    je ne pense pas que ce soit la bonne solution, je pense qu'il faut trouver d'où viens ton écrasement mémoire. Tu peux tenter avec un watch sur l'adresse
    memoire avec gdb.
    il y a quelque chose de bizard dans ton code si tu passe par une autre
    méthode tu retrouvera une erreur bizard ailleur.
    bye,
    Merci Krieg,
    Justement, j' en suis quasiment certain, je rencontre cette erreur après avoir éxécuté un :

    memcpy(dataOut, dataIn, sizeof(dataIn)); // sizeof(dataIn) vaut 400 bytes

    Après avoir fait ce memcpy, si j'essaye d'appeler ma fonction de callback, j'ai une erreur de segmentation, alors qu'avant ce memecpy, mon callback s'execute bien.
    Je pense que c'est lié à l'écrasement de son pointeur.

    Sinon comment procéder pour mettre en "DUR" cette adresse de callback pour pouvoir lui attribuer une zone mémoire "fixe" ?
    Sachant que ce callback a maintenant été ajouté à une structure qui est initialisé à l'Init du main, et qui est donné en paramètre dans ma fonction de thread.

    Merci d'avance pour vos réponses

    Cordialement,

    Moulefrite

  13. #13
    Membre régulier Avatar de krieg
    Profil pro
    Inscrit en
    janvier 2009
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : janvier 2009
    Messages : 75
    Points : 92
    Points
    92
    Par défaut
    Salut,
    Citation Envoyé par moulefrite Voir le message
    memcpy(dataOut, dataIn, sizeof(dataIn)); // sizeof(dataIn) vaut 400 bytes
    As tu bien alloué un bloc de taille suffisant pour dataOut?
    Tu ne devrai pas avoir ce genre de problème avec memcpy.

  14. #14
    Débutant
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    janvier 2004
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : janvier 2004
    Messages : 452
    Points : 324
    Points
    324
    Par défaut
    Citation Envoyé par krieg Voir le message
    Salut,

    As tu bien alloué un bloc de taille suffisant pour dataOut?
    Tu ne devrai pas avoir ce genre de problème avec memcpy.
    Justement, c'est bien le cas, en faites ce dataOut, est une structure qui est crée dans le Main() ;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int main(void)
    {
         STRUCT_RESP respT;
     
         memset(respT, 0, sizeof(STRUCT_RESP));
     
         .....
    }
    Je pense aussi à la meme chose que toi, pourtant je ne vois vraiment pas d'ou ca peu provenir.

    Merci encore Krieg pour ton aide

  15. #15
    Membre régulier Avatar de krieg
    Profil pro
    Inscrit en
    janvier 2009
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : janvier 2009
    Messages : 75
    Points : 92
    Points
    92
    Par défaut
    Salut,
    je sais pas si ton code est conséquent, mais si tu peux le poster entièrement je peux essayer d'y regarder.

  16. #16
    Débutant
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    janvier 2004
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : janvier 2004
    Messages : 452
    Points : 324
    Points
    324
    Par défaut
    Citation Envoyé par krieg Voir le message
    Salut,
    je sais pas si ton code est conséquent, mais si tu peux le poster entièrement je peux essayer d'y regarder.

    C'est bon j'ai trouvé d'ou provenais mon erreur, c'etait bien une allocation mémoire qui etait manquante, (honte à moi de pas l'avoir vue dès le départ )

    En tout cas, problème de segmentation résolu grace à toi Krieg, et problème de passage d'un pointeur de fonction par le biai d'une structure résolu.

    Merci à vous 2 Médinoc et Krieg pour votre aides.

    Sujet Résolu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/05/2011, 12h48
  2. [VBA-Excel]Avoir une boite de dialogue avec les arguments des fonctions ?
    Par EvaristeGaloisBis dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 29/05/2007, 09h37
  3. Réponses: 3
    Dernier message: 25/07/2006, 09h25
  4. [JAVASCRIPT] passage d'argument à une fonction
    Par LE NEINDRE dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 03/06/2005, 18h17
  5. Passer une fonction comme argument à une fonction
    Par Cocotier974 dans le forum Général Python
    Réponses: 4
    Dernier message: 29/06/2004, 13h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo