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

C Discussion :

thread et structure


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 5
    Points : 1
    Points
    1
    Par défaut thread et structure
    Bonjour à tous,

    après une certain nombre de recherche je me trouve bien bloqué
    j'essaye de mettre des thread dans mon programme de façon à accélérer certaine partie de mon programme tout en essayant d'utiliser au mieux les cœurs de ma machine.

    Mon problème:
    J'ai une structure StructAgent composer de deux éléments un identifiant et un pointeur sur la structure suivante

    à partir de la j'ai une liste de structure pas compliqué.

    mon problème est dans la suppression du premier élément de la liste.

    j'appelle ma fonction avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pthread_create (&supAgent_thread, NULL, sup_agent2, StructAgent);
    jusque la tous marche bien

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    void *sup_agent2(void *Agent)
    {
    	unAgent *tmp2 = (unAgent*) Agent;
    	unAgent *tmp = (unAgent*) (Agent);
     
    	//nextlist
    	tmp2 = (tmp2)->suivant;
    	while(tmp2 != NULL)
    	{
    		if((tmp2)->energie <= 0) 
    		{
    			(*tmp).suivant = (*tmp2).suivant;
    			free(tmp2);
    			tmp2 = (tmp)->suivant;
    		}
    		else
    		{
    			tmp = (tmp)->suivant;
    			tmp2 = (tmp2)->suivant;
    		}
    	}
     
    	// firstlist
    	unAgent *tmp3 = (unAgent*) (Agent);
    	unAgent *tmp4 = (unAgent*) (&Agent);
    	if( (tmp3)->energie <= 0)
    	{
    		tmp4 = (tmp3)->suivant;
    		free(tmp3);
    	}
    	return NULL;
    }
    mon problème vient des dernière ligne du code soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	// firstlist
    	unAgent *tmp3 = (unAgent*) (Agent);
    	unAgent *tmp4 = (unAgent*) (&Agent);
    	if( (tmp3)->energie <= 0)
    	{
    		tmp4 = (tmp3)->suivant;
    		free(tmp3);
    	}
    quand j'insère la structure suivante ((tmp3)->suivant) à la racine (mon pointeur de base Agent) j'ai une belle erreur de segmentation.

    le problème doit être simple mais je tourne un peu en rond depuis un bon moment, je dois me tromper à un endroit.

    J'ai fais le tour ses faqs mais en utilisant thread je n'ai plus de pointeur de pointeur.
    La méthode ci-dessous plante aussi et la je me retrouve coincé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	// firstlist
    	unAgent *tmp3 = (unAgent*) (Agent);
    	if( (tmp3)->energie <= 0)
    	{
    		Agent = (tmp3)->suivant;
    		free(tmp3);
    	}
    Merci de vos réponses

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    cette ligne pose problème : unAgent *tmp4 = (unAgent*) (&Agent);
    Il semble que &Agent pointe sur une adresse qui ne t'a pas été alouée, d'où le segmentation fault.

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    merci feydaykyn
    j'ai constaté exactement le problème que tu cite car je fais une duplication de la source et je ne cible pas l adresse source

    ma deuxième solution ou je modifie directement Agent ne passe pas non plus même erreur constaté

    pour l'instant j'ai résolu le problème en passant par une structure globale et je modifie l'origine directement
    mais je ne veux pas passer par une globale et je voudrai pouvoir directement modifier ma structure à partir des adresses

    Habituellement je fais des pointeurs de pointeur qui me permettent de cibler directement l'adresse source mais utilisant thread je ne peu pas passer un pointeur de pointeur mais un simple pointeur.

    je continu à regarder mais je ne vois toujours pas la solution.

  4. #4
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Ce n'est pas parce qu'on peut transtyper void * en un pointeur quelconque que cela est justifié : on ne doit transtyper un void * qu'en une adresse du type correspondant exactement à l'objet pointé.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	unAgent *tmp3 = (unAgent*) (Agent);
    	unAgent *tmp4 = (unAgent*) (&Agent);
    Ces deux lignes sont incompatibles : Si Agent est effectivement un pointeur sur un unAgent, alors &Agent ne peut pas l'être (et réciproquement).

    D'autre part, Agent est une variable locale et &Agent donne l'adresse de cette variable locale.

    tmp4 est aussi une variable locale et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    		tmp4 = (tmp3)->suivant;
    ne fait que modifier cette variable locale.

    Habituellement je fais des pointeurs de pointeur qui me permettent de cibler directement l'adresse source mais utilisant thread je ne peu pas passer un pointeur de pointeur mais un simple pointeur.
    Mais un pointeur de pointeur n'est qu'un cas particulier d'un pointeur et il n'y a rien de spécifique à ce cas. Rien n'empêche de passer un pointeur de pointeur. Du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    unAgent *StructAgent;
    .....
    pthread_create (&supAgent_thread, NULL, sup_agent2, &StructAgent);
     
    void *sup_agent2(void *Agent)
    {
    	unAgent ** adlist = Agent;
    	unAgent *tmp  = *adlist ;
    	unAgent *tmp2 = *adlist 
    ....
            *adlist = ...
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    merci pour la réponse mais tous ceci ne m'aide pas car quand je parle de pointeur de pointeur je parle de cibler l'adresse source et non dupliquer les pointeurs.

    mon problème est l'adresse initiale que je n'arrive pas à cibler directement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    unAgent *tmp3 = (unAgent*) (Agent);
    unAgent *tmp4 = (unAgent*) (&Agent);
    ceci n'était qu'un simple exemple de ce que je tenté de faire pour cibler l'adresse source.

    En ce qui concerne mon problème je ne voix pas comment le résoudre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pthread_create (&supAgent_thread, NULL, sup_agent2, &StructAgent);
    ceci ne fonctionne pas car dans le code source de de la bibliothèque pthread la quatrième partie est un pointeur simple et non un double pointeur, donc ceci générera une erreur d'incompatibilité de type.

  6. #6
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    ceci ne fonctionne pas car dans le code source de de la bibliothèque pthread la quatrième partie est un pointeur simple et non un double pointeur, donc ceci générera une erreur d'incompatibilité de type.
    Un pointeur sur un pointeur n'a rien de particulier par rapport aux autres genres de pointeur.
    Le prototype de pthread_create() est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);
    Le quatrième paramètre est donc un void * compatible avec un &StructAgent, même si &StructAgent est un unAgent **
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    oui mais comme dis ceci fais une copie du départ et ne cible pas directement l'adresse source.

    j'utilise les pointeurs depuis un bon moment et c'est bien la première fois que je me retrouve coincé dans un tel cas.

    Donc mon problème est juste de trouver une solution qui puisse me faire modifier le pointeur de base (StructAgent) et de lui dire de pointer sur l'élément suivant et non sur le premier élément. sans passer par une structure globale.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Ce n'est pas une copie du départ avec la maniere que te propose Diogene, revoit le fonctionnement des pointeurs.
    Par exemple :

    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
    24
     
    #include        <stdlib.h>
    #include        <stdio.h>
     
    void            modif_ptr(void *ptr)
    {
      int           **j;
     
      j = (int **) ptr;
      **j = 15;
    }
     
    int             main()
    {
      int           *i;
     
      i = malloc(sizeof(int));
      *i = 5;
      printf("i = %d\n", *i);
      modif_ptr(&i);
      printf("i = %d\n", *i);
      free(i);
      return (0);
    }
    Comme tu peux voir, i est bien modifié par la fonction modif_ptr. Note le "void *" dans le prototype de cette fonction, et le fait qu'elle reçoit pourtant un "int **", ce qui est une particularité du pointeur void * de pouvoir tout accepter. C'est bien entendu fort dangereux, puisque dans ce cas il n'y a plus de vérification de type.
    Tu devrais maintenant pouvoir revoir ton code et faire en sorte que ton thread modifie ta structure.
    Au passage, il n'y a pas de mutex sur ta stucture, si le thread n'est pas le seul à s'en servir tu auras rapidement des erreurs...

  9. #9
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Donc mon problème est juste de trouver une solution qui puisse me faire modifier le pointeur de base (StructAgent) et de lui dire de pointer sur l'élément suivant et non sur le premier élément. sans passer par une structure globale
    Difficilement compréhensible !

    Si je comprend, ton code a pour but de supprimer d'une liste simplement chainée les éléments dont le champ energie est négatif ou nul.
    Une telle opération étant susceptible de détruire le premier élément de la liste, il faut pouvoir modifier le pointeur sur le premier élément de la liste.

    Je répète donc ce que j'ai dit dans mes posts précédent :

    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
    24
    25
    26
    27
    28
    29
    unAgent *StructAgent;  // Pointeur sur la tête de liste
    .....
    pthread_create (&supAgent_thread, NULL, sup_agent2, &StructAgent);
    ....
    void *sup_agent2(void *pliste)
    {
       unAgent ** adlist = pliste; // adresse du pointeur sur la tête de liste
       unAgent *tmp  = *adlist ;   // pointe le premier élément de la liste
       unAgent *tmp2 ;
       if(tmp != NULL)             // si la liste n'est pas vide
       {
           while( (tmp2 = tmp->suivant) != NULL)
           {
               if(tmp2->energie <= 0) 
               {
                  tmp->suivant = tmp2->suivant;
                  free(tmp2);	
               }
               else  tmp = tmp->suivant;
           }
           tmp  = *adlist          // traitement du premier élément de la liste
           if(tmp->energie <= 0)
           {
              *adlist = tmp->suivant; // changer la tête de liste		
              free(tmp);
           }
       }
       return NULL;
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  10. #10
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    ok Merci mon problème est résolue

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pthread_create (&supAgent_thread, NULL, sup_agent2, &StructAgent);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    unAgent ** adlist = Agent;
    unAgent *tmp3 = * adlist;
    // firstlist
    if( tmp3->energie <= 0)
    {
    	*adlist = tmp3->suivant;
    	free(tmp3);
    }
    mon problème était qu'à la première ligne je mettaient *Agent donc tous que vous m aviez dis me générer la même erreur
    diogene désolé de la gène c'est en faisant un copier coller du code que tu as mi que je me suis rendue conte de cette étoile en trop me dupliqué le pointeur.

    Je vous remercie pour votre aide

    en ce qui concerne le void merci de vos information je suis retourné lire le manuel et j'avais mal saisie certains points.

Discussions similaires

  1. [Win] Thread passage Structure pointeur Vector + string
    Par jerem3000 dans le forum Threads & Processus
    Réponses: 2
    Dernier message: 31/10/2012, 15h24
  2. Thread et structure
    Par arnoreffay dans le forum POSIX
    Réponses: 30
    Dernier message: 28/10/2012, 17h41
  3. [Thread] Qt et multithread, structure ou conception
    Par alpha_one_x86 dans le forum Multithreading
    Réponses: 3
    Dernier message: 13/04/2008, 12h42
  4. Envoie de structure à un thread.
    Par mohdaef dans le forum Threads & Processus
    Réponses: 2
    Dernier message: 24/03/2008, 17h23
  5. Thread Synchronisation avec structure FIFO ??
    Par vincedom dans le forum MFC
    Réponses: 5
    Dernier message: 30/03/2006, 06h00

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