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

Threads & Processus C++ Discussion :

Ecrasement de variable


Sujet :

Threads & Processus C++

  1. #1
    Membre confirm�
    Inscrit en
    Juillet 2004
    Messages
    113
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 113
    Par d�faut Ecrasement de variable
    Bonsoir,

    Dans une boucle, je cr�e plusieurs Threads pointant sur une m�me fonction. Or une des variable de cette fonction est �cras�e lors du 2eme appel de cette fonction. Je me retrouve avec 2 fois le m�me r�sultat au lieu de 2 diff�rents.

    J'ai mis en place une section critique comme je l'ai lu � plusieurs endroits, mais rien n'y fait.

    Y aurait-il quelque chose que je n'aurais pas compris ?

    Voila mon 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
     
    long C_TrtExec::Executer(void)
    {
    long i;
    struct S_ThreadParam sO_ThreadParam;
    HANDLE lO_ThreadId;
     
     
    	for (i=0 ; i<cI_NbTrt ; i++) {
     
    		sO_ThreadParam.sO_TrtExec = this;
    		sO_ThreadParam.sO_Trt = cO_ListeTrt[i]; // *** Info envoyée au thread qui est différente ici à chaque appel mais qui ne l'est plus dans le thread
     
    		lO_ThreadId = CreateThread(NULL, 0, ThreadLauncher, &sO_ThreadParam, 0, NULL);
     
    		AddThread(lO_ThreadId)// Ajoute simplement le ThreadId dans une liste pour le WaitForMultipleObjects
     
    	}
     
    	WaitForMultipleObjects( cI_NbThread, cO_ListeThread, TRUE, INFINITE);
     
    	DelAllThread();
     
    	return 0;
    }
    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
     
     
    DWORD WINAPI ThreadLauncher(void *pO_ThreadParam)
    {
    	EnterCriticalSection(&cO_CriticalSection); // cO_CriticalSection déclaré global
     
    	struct S_ThreadParam *lO_ThreadParam = reinterpret_cast<struct S_ThreadParam *>(pO_ThreadParam);
    	C_TrtExec *lO_TrtExec = lO_ThreadParam->sO_TrtExec;                          
    	lO_TrtExec->TrtThread(lO_ThreadParam->sO_Trt); // Au deuxième appel, sO_Trt vaut la meme chose qu'au premier appel
     
    	LeaveCriticalSection(&cO_CriticalSection);
     
    	return 0;   
     
    }
    Merci de voter aide...

  2. #2
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    �tudiant
    Inscrit en
    F�vrier 2012
    Messages
    788
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 35
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : F�vrier 2012
    Messages : 788
    Par d�faut
    Le code est �tonnamment compliqu� pour ce qu'il est cens� faire (?)
    En C++11, il existe std::thread. http://en.cppreference.com/w/cpp/thread/thread
    En C++ sinon, il y a boost::thread.
    OpenMP peut �tre aussi int�ressant.

    As-tu fait un affichage avant la modification par les threads de lO_ThreadParam->sO_Trt (pour v�rifier que la valeur est bien modifi�e) ?
    As-tu fait un affichage juste apr�s �tre entr� et juste avant de sortir de la section critique (en augmentant la dur�e du calcul � l'int�rieur avec un sleep(10)) pour �tre s�r qu'elle soit respect�e ?

  3. #3
    Membre confirm�
    Inscrit en
    Juillet 2004
    Messages
    113
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 113
    Par d�faut
    Citation Envoy� par Ehonn Voir le message
    Le code est �tonnamment pour ce qu'il est cens� faire (?)
    Qu'entends-tu par �tonnamment long ?
    Citation Envoy� par Ehonn Voir le message
    En C++11, il existe std::thread. http://en.cppreference.com/w/cpp/thread/thread
    En C++ sinon, il y a boost::thread.
    OpenMP peut �tre aussi int�ressant.
    Ok, je vais jeter un coup d'oeil � ca !!!
    Citation Envoy� par Ehonn Voir le message
    As-tu fait un affichage avant la modification par les threads de lO_ThreadParam->sO_Trt (pour v�rifier que la valeur est bien modifi�e) ?
    Oui, j'ai une log (j'ai enlev� les appels dans ce post), j'ai affich� l'objet avant de le passer au Thread ainsi que dans la fonction lO_TrtExec->TrtThread
    Citation Envoy� par Ehonn Voir le message
    As-tu fait un affichage juste apr�s �tre entr� et juste avant de sortir de la section critique (en augmentant la dur�e du calcul � l'int�rieur avec un sleep(10)) pour �tre s�r qu'elle soit respect�e ?
    Non... je m'y mets...

  4. #4
    Membre Expert
    Homme Profil pro
    �tudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par d�faut
    Citation Envoy� par xc78370 Voir le message
    Qu'entends-tu par �tonnamment long ?
    C'est pas vraiment la longueur le soucis, c'est plut�t le fait de faire un code non portable alors que le C++ fourni tout ce qu'il faut pour faire �a simplement, de mani�re portable (std::thread depuis C++11, boost::thread avant)

    Sinon pour ton probl�me, tu n'envoi que l'adresse de la structure qui contient tes params � tes threads.

    Tu n'as donc q'un seul objet ThreadParam existant, et tous les threads ont forc�ment les m�mes param�tres.

  5. #5
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    �tudiant
    Inscrit en
    F�vrier 2012
    Messages
    788
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 35
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : F�vrier 2012
    Messages : 788
    Par d�faut
    Citation Envoy� par Ehonn Voir le message
    Le code est �tonnamment pour ce qu'il est cens� faire (?)
    �tonnamment compliqu�* (j'ai oubli� un mot).

  6. #6
    Membre confirm�
    Inscrit en
    Juillet 2004
    Messages
    113
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 113
    Par d�faut
    Citation Envoy� par Iradrille Voir le message
    C'est pas vraiment la longueur le soucis, c'est plut�t le fait de faire un code non portable alors que le C++ fourni tout ce qu'il faut pour faire �a simplement, de mani�re portable (std::thread depuis C++11, boost::thread avant)
    OK, j'avoue que je ne fais pas trop gaffe � �a, d�veloppant tout le temps pour la meme plateforme... Je vais y faire attention.
    Citation Envoy� par Iradrille Voir le message
    Sinon pour ton probl�me, tu n'envoi que l'adresse de la structure qui contient tes params � tes threads.

    Tu n'as donc q'un seul objet ThreadParam existant, et tous les threads ont forc�ment les m�mes param�tres.
    On ne peut pas envoyer autre chose qu'un pointeur � Createthread...

  7. #7
    Membre confirm�
    Inscrit en
    Juillet 2004
    Messages
    113
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 113
    Par d�faut
    Citation Envoy� par Ehonn Voir le message
    �tonnamment compliqu�* (j'ai oubli� un mot).
    ??? C'est � dire ?

  8. #8
    Membre Expert
    Homme Profil pro
    �tudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par d�faut
    Citation Envoy� par xc78370 Voir le message
    On ne peut pas envoyer autre chose qu'un pointeur � Createthread...
    Utilise un tableau (si cI_NbTrt est une constante de compilation), un vector sinon.

    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
    long C_TrtExec::Executer(void)
    {
    	long i;
    	struct S_ThreadParam sO_ThreadParam[cI_NbTrt];
    	HANDLE lO_ThreadId;
     
     
    	for (i=0 ; i<cI_NbTrt ; i++) {		
    		sO_ThreadParam[i].sO_TrtExec = this;
    		sO_ThreadParam[i].sO_Trt = cO_ListeTrt[i]; // *** Info envoyée au thread qui est différente ici à chaque appel mais qui ne l'est plus dans le thread
     
    		lO_ThreadId = CreateThread(NULL, 0, ThreadLauncher, &sO_ThreadParam[i], 0, NULL);
     
    		AddThread(lO_ThreadId)// Ajoute simplement le ThreadId dans une liste pour le WaitForMultipleObjects
     
    	}
     
    	WaitForMultipleObjects( cI_NbThread, cO_ListeThread, TRUE, INFINITE);
     
    	DelAllThread();
     
    	return 0;
    }

  9. #9
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    D�tails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par d�faut
    Vu qu'un thread met un peu de temps avant de se lancer il est tr�s probable que la boucle for soit d�j� termin�e lorsque les ci_Nbtr threads d�marrent pour de bon en appelant la fonction ThreadLauncher, et comme ils prennent tous en param�tre un pointeur vers la m�me structure sO_ThreadParam, ils partagent tous le m�me champ sO_Trt.

    Il faut remplacer cette structure par un tableau et donner au i�me thread l'adresse de la i�me structure
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    S_ThreadParam sO_ThreadParam[NbTrt ];
    Autre chose, je ne sais pas trop quel est le but recherch� avec tous ces threads mais dans le code montr� ils ne servent � rien du tout. Comme la fonction ThreadLauncher est prot�g� par un mutex, tous les thread vont attendre un par un que le mutex se lib�re et la fonction TrtThread () va �tre appel� � tour de r�le, exactement comme si on avait �crit :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    for (i=0 ; i< cI_NbTrt ; i++) 
    {
        TrtThread(cO_ListeTrt[i]);
    }

  10. #10
    Membre confirm�
    Inscrit en
    Juillet 2004
    Messages
    113
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 113
    Par d�faut
    Citation Envoy� par Arzar Voir le message
    Vu qu'un thread met un peu de temps avant de se lancer il est tr�s probable que la boucle for soit d�j� termin�e lorsque les ci_Nbtr threads d�marrent pour de bon en appelant la fonction ThreadLauncher, et comme ils prennent tous en param�tre un pointeur vers la m�me structure sO_ThreadParam, ils partagent tous le m�me champ sO_Trt.

    Il faut remplacer cette structure par un tableau et donner au i�me thread l'adresse de la i�me structure
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    S_ThreadParam sO_ThreadParam[NbTrt ];
    Autre chose, je ne sais pas trop quel est le but recherch� avec tous ces threads mais dans le code montr� ils ne servent � rien du tout. Comme la fonction ThreadLauncher est prot�g� par un mutex, tous les thread vont attendre un par un que le mutex se lib�re et la fonction TrtThread () va �tre appel� � tour de r�le, exactement comme si on avait �crit :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    for (i=0 ; i< cI_NbTrt ; i++) 
    {
        TrtThread(cO_ListeTrt[i]);
    }
    Merci beaucoup. J'ai effectivement suivi le conseil d'Iradrille (qui est le m�me que le tient Arzar) et cela fonctionne ...
    Au final la section critique n'apportait rien, je l'ai donc enlev�e.
    Concernant la portabilit� de mon code, je vais m'attacher � faire attention.

    Merci � tous.

  11. #11
    Membre Expert
    Homme Profil pro
    �tudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par d�faut
    Citation Envoy� par xc78370 Voir le message
    Au final la section critique n'apportait rien, je l'ai donc enlev�e.
    Concernant la portabilit� de mon code, je vais m'attacher � faire attention.
    A titre d'exemple, le m�me code en utilisant des std::thread (pas test� pas de compilo suportant C++11 sous la main )
    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
    long C_TrtExec::Executer() {
    	std::vector<std::thread> threads;
     
    	for (long i=0; i<cI_NbTrt; ++i) {	
    		S_ThreadParam sO_ThreadParam;	
    		sO_ThreadParam.sO_TrtExec = this;
    		sO_ThreadParam.sO_Trt = cO_ListeTrt[i];
     
    		// passage du paramètre par copie
    		threads.push_back(std::thread(ThreadLauncher, sO_ThreadParam));
    	}
     
    	for(auto t: threads) {
    		t.join();
    	}
     
    	return 0;
    }
     
    void ThreadLauncher(pO_ThreadParam) {
    	pO_ThreadParam.sO_TrtExec(pO_ThreadParam.sO_Trt);
    }

  12. #12
    Membre confirm�
    Inscrit en
    Juillet 2004
    Messages
    113
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 113
    Par d�faut
    Citation Envoy� par Iradrille Voir le message
    A titre d'exemple, le m�me code en utilisant des std::thread (pas test� pas de compilo suportant C++11 sous la main )
    Merci pour le code, mais je suis comme toi, je travaille en VCPP6 ()

  13. #13
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    �tudiant
    Inscrit en
    F�vrier 2012
    Messages
    788
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 35
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : F�vrier 2012
    Messages : 788
    Par d�faut
    Voici une utilisation de std::thread et std::mutex
    Avec une fonction et une lamda_function (juste pour l'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
    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
    // g++ -Wall -Wextra -std=c++11 -pedantic thread_mutex.cpp -o thread_mutex && ./thread_mutex
     
    #include <iostream>
    #include <chrono>
    #include <thread>
    #include <mutex>
     
     
    // Fonction pour le thread
    void fct(int & v, std::mutex & m)
    {
    	std::cout << "Avant mutex\n";
    	m.lock();
     
    	std::cout << "Début mutex\n";
     
    	// On dort 10 secondes
    	std::this_thread::sleep_for(std::chrono::seconds(10));
     
    	// On incrémente la valeur
    	++v;
     
    	std::cout << "Fin mutex\n";
    	m.unlock();
    }
     
     
    int main()
    {
    	// On peut aussi utiliser une lambda fonction
    	auto lambda_fct = [](int & v, std::mutex & m) -> void
    	{
    		std::cout << "Avant mutex\n";
    		m.lock();
     
    		std::cout << "Début mutex\n";
     
    		// On dort 10 secondes
    		std::this_thread::sleep_for(std::chrono::seconds(10));
     
    		// On incrémente la valeur
    		++v;
     
    		std::cout << "Fin mutex\n";
    		m.unlock();
    	};
     
    	int v = 0;
    	std::mutex m;
     
    	std::thread t0(lambda_fct, std::ref(v), std::ref(m));
    	std::thread t1(fct,        std::ref(v), std::ref(m));
     
    	t0.join();
    	t1.join();
     
    	std::cout << "Valeur finale de v = " << v << std::endl;
     
    	return 0;
    }

  14. #14
    Membre confirm�
    Inscrit en
    Juillet 2004
    Messages
    113
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 113
    Par d�faut
    Ok merci pour le code.

    Je garde ca sous le coude pour des jours meilleurs !!!!

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Ecrasement des valeurs apr�s le transfert de la variable dans une autre classe.
    Par patriot dans le forum D�veloppement Mobile en Java
    R�ponses: 0
    Dernier message: 13/05/2011, 11h39
  2. probleme d ecrasement de variable
    Par goomie dans le forum Wildfly/JBoss
    R�ponses: 0
    Dernier message: 05/01/2011, 13h48
  3. Ecraser le contenu d'une variable
    Par L'aigle de Carthage dans le forum Langage
    R�ponses: 23
    Dernier message: 07/05/2008, 11h37
  4. Construire un formulaire qui ecrase les variables hidden
    Par Battosaiii dans le forum Servlets/JSP
    R�ponses: 7
    Dernier message: 14/04/2006, 11h58
  5. [POO] petite kh�le variable ecras�e
    Par jeff_! dans le forum Langage
    R�ponses: 5
    Dernier message: 01/02/2006, 21h13

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