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 :

Problème avec pthread


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Par défaut Problème avec pthread
    Bonjour,

    Je dois développer un programme C avec pthread. Ayant peu d'expérience avec cette technique je me suis d'abord attaché à faire quelques tests et je suis tombé sur un OS.

    En sachant que sur ma machine en tout cas, le programme copier collé du prof et celui tiré d'ici : franckh.developpez.com/tutoriels/posix/pthreads/ me font le même problème..

    Voilà le code :

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    int Treatment(char *as_TreatmentDat, int nbThreads)
    {
     	long  	ll_CountDeleteClientRatingDetail = 0,
     		ll_CountRatingScore 		 = 0;
     	int 	li_rc = 0, i = 0, status = 0;
     
     	pthread_t callThread[nbThreads];
     
     	 /* Initialisation du mutex */
     
     	pthread_mutex_init(&thdData.mutex, NULL);
     
     	/* On compte le nombre de lignes dans rating_score */
     
    	ll_CountRatingScore = 893564;
     
     	/* Avec ca, on compte le nombre de ligne à traiter par thread */
     
     	thdData.nbrOfRowToDo = ll_CountRatingScore / nbThreads;
     
     	/* Création des threads en leur disant leur "nom" afin qu'ils puissent savoir quelles lignes traiter. */
     
     	for(i = 0; i < nbThreads; i++)
     	{
      		pthread_create(&callThread[i], NULL, treatmentThread, &i);
     	}	
     
     	/* Attende de la fin des threads */
     
     	for(i = 0; i < nbThreads; i++)
     	{
     		pthread_join(callThread[i], (void **)&status);
     	}
     
     	/* Destruction du mutex */
     
     	pthread_mutex_destroy(&thdData.mutex);
     
     	return li_rc;
    }
     
    /* Fonction executée par les threads */
     
    void *treatmentThread(void *arg)
    {
    	int   	li_rc                            = 0;       		
           	int	threadCounter			 = 0;
    	int thdNum = *(int *)arg;
     
    	/* On calcule la fourchettes de lignes à traiter grâce au numéro du thread */ 
     
    	long start = 1 + (thdData.nbrOfRowToDo * thdNum);
    	long end = thdData.nbrOfRowToDo * (thdNum + 1);
     
    	printf("ceci est i : %d\n", &arg);
    	printf("Ich bin da thread n°%d et j'ai fait %ld rows!\n",thdNum, threadCounter);
    	printf("Mein start was %ld and mein endish was %ld\n", start, end);
     
    	pthread_exit((void*) 0);
    }
    Et voici le magnifique résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Ich bin da thread n°2 et j'ai fait 0 rows!
    Mein start was 1787129 and mein endish was 2680692 
     
    Ich bin da thread n°2 et j'ai fait 0 rows!
    Mein start was 1787129 and mein endish was 2680692
     
    Ich bin da thread n°3 et j'ai fait 0 rows!
    Mein start was 2680693 and mein endish was 3574256
     
    Ich bin da thread n°3 et j'ai fait 0 rows!
    Mein start was 2680693 and mein endish was 3574256
    J'ai executé le programme plusieurs fois, et parfois c'est 0, 1, 2 et 2 ou 1, 1, 3 et 3.... Je comprend pas ? Mais alors pas du tout.

    En théorie il est censé envoyé i à la fonction et donc chaque thread à bien un i différent à chaque fois non? Vu qu'il crée le thread, puis incrémente i puis crée un autre thread...

    Je me souviens pas avoir eu le problème au cours avec le même genre de programme et cela m'étonnerait que le programme de frenchktzefzrg ne fonctionne pas.

    Ca peut venir du compilateur? Ou bien y'a une erreur totalement stupide que je vois pas?

    Un grand merci,
    Albin.

  2. #2
    Membre Expert Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    Dans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     	for(i = 0; i < nbThreads; i++)
     	{
      		pthread_create(&callThread[i], NULL, treatmentThread, &i);
     	}
    tu créée des threads très vite.
    Donc, tu lances le 1er thread et dans la foulée tu fais i++.
    Donc si ce thread met du temps à démarrer, il va voir "i+1" et plus "i".

    A mon avis, si tu endors l'appelant qq millisecondes, ton affichage sera correct.

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Par défaut
    Bonjour,

    Merci de la réponse même si j'y avais pensé aussi, cela me semble étrange que mon prof qui est spécialisé dans les applications temps réels (en gros multi-thread, informatique parallèle, etc...) se plante aussi bêtement...

    Sinon dans le tuto en ligne que j'ai link ci-dessus, au lieu de faire &i, il fait :

    Mais chez moi cela ne veut pas compiler : "Must be a scalar type". Est-ce que cela serait la solution? Il faudrait lui envoyer la valeur de i et non un pointeur vers i mais vu que la fonction du thread attend un pointeur, comment faire?

    Je suis un jeune qui a apprit au Java, j'ai un peu de mal à jouer avec les pointeurs..

    Merci d'avance,
    Albin.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    le problème vient de ce qu'indique fregolo.

    Dans ton programme, dans la gestion du thread, tu as
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int thdNum = *(int *)arg;
    Mais si i a changé de valeur, le thread prendra la valeur actuelle de i, donc la "mauvaise", puisqu'il récupère la valeur à l'adresse de i.

    Mais le cast de i en void* devrait fonctionner, quelle est l'erreur retournée ? Je n'en ai aucune chez moi. A ce moment-là il va caster la valeur de i en void*, à ne surtout pas utiliser comme pointeur .
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre Expert Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    En effet, je n'avais pas fait gaffe, dans le tuto, le pointeur est en fait la valeur !!

    Je n'ai pas l'habitude de travailler comme ça, mais oui, pour être sûre de la valeur de ton identifiant, c'est la bonne solution.

    Il faudrait lui envoyer la valeur de i et non un pointeur vers i mais vu que la fonction du thread attend un pointeur, comment faire?
    Un pointeur est une adresse, donc en général l'adresse est codée sur un "int" donc rien ne t’empêche de faire croire que tu passes un pointeur alors que tu passes une valeur entière.

    Java et C n'ont pas les même subtilités!

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Novembre 2011
    Messages : 25
    Par défaut
    Hey ben un grand merci à tous les deux, cela fonctionne maintenant...

    J'avais un erreur de type : "Must be a scalar type". Mais je ne l'ai plus, je devai avoir fait une autre erreur qui se couplait à ce changement... parfois c'est bien de tout réécrire :p.

    Je savais pour les pointeurs (que ce n'est qu'une adresse mémoire) mais par contre j'avais pas pensé à "berner" la fonction avec !

    Encore un grand merci,
    Albin.

  7. #7
    Expert confirmé
    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
    Par défaut
    @fregolo52
    donc en général l'adresse est codée sur un "int"...
    Rien ne permet d'affirmer cela. C'est dépendant de la machine.
    Il existe des types entiers (optionnels) qui permettent de "placer" une adresse dans un entier : intptr_t ou uintptr_t.

    Si des données doivent être communiquées aux threads, on peut les rassembler dans une structure et passer l'adresse de la structure.
    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
    typedef struct
    {
       pthread_t idt;
       int thdNum;
    //...autres données utiles au thread
    }TDataThreads;
    ....
     
     TDataThreads callThread[nbThreads];
     for(i = 0; i < nbThreads; i++)
     {
         callThread[i].thdnum = i;		
         pthread_create(&callThread[i].idt, NULL, treatmentThread, callThread+i);
     }
     
    void *treatmentThread(void *arg)
    {
    	int   	li_rc                            = 0;       		
           	int	threadCounter			 = 0;
    	TDataThreads * data = (TDataThreads *)arg;
            int thdNum = data->thdNum;
    ....

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

Discussions similaires

  1. Problème des 8 queens avec pThreads
    Par Denar dans le forum Threads & Processus
    Réponses: 2
    Dernier message: 15/02/2011, 23h58
  2. Problème Programmation avec Pthreads
    Par TSUS86 dans le forum Threads & Processus
    Réponses: 6
    Dernier message: 28/03/2010, 14h54
  3. [Pthreads/Windows] Problème avec pthread_t
    Par dapounet dans le forum POSIX
    Réponses: 18
    Dernier message: 22/10/2008, 22h01
  4. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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