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

Visual C++ Discussion :

Fermeture de thread/Stopper recvfrom


Sujet :

Visual C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut Fermeture de thread/Stopper recvfrom
    Bonsoir,

    Le contexte: réaliser un serveur bootp qui tourne dans un thread.

    Mon soucis est lorque je désire terminer le thread.
    1) Lorsque le thread se termine, j'ai une erreur windows 0xc0000005. A ce que je compris, cela provient des variables dynamiques non libérées.
    Pourtant je me suis inspiré de la FAQ pour gérer cela sous forme d'événements.
    Comment arreter un thread de travail?

    2) Mon deuxième soucis est de stopper la fonction recvfrom qui est bloquante.
    J'ai effectué diverses tentatives mais aucune s'est avéré fonctionnées.

    Voici des bouts de code pour illustrer l'affaire:
    (En commentaire, les différentes tentatives que j'ai pu faire)

    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
     
    /*************************************************************************
      erreur: Ferme le socket
     
      Valeur de retour:
     
      15/11/2006
    *************************************************************************/
    void bootps::erreur()
    {
    	/*if(WSAAsyncSelect(bootps_socket, (HWND)m_hThread, 0, FD_CLOSE) != 0){
    		trace("WSAAsyncSelect a echoue\n");
    		int numError = WSAGetLastError();
    	}*/
    /*Le teste echoue...*/
     
    	/*if (WSAEventSelect(bootps_socket, m_hThread, FD_CLOSE) != 0){
    		trace("WSAEventSelect a echoue\n");
    	}*/
    /*Le teste echoue...*/
     
    	if (shutdown(bootps_socket,SD_BOTH) != 0)
    		trace("shutdown a échoue\n");
     
    	if(closesocket(bootps_socket) !=0)
    		trace("Erreur fermeture socket\n");
    	::WSACleanup();
    }
    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
     
    /*************************************************************************
      stopThreadServeur: Stop le thread du serveur bootp.
     
      Valeur de retour:
            true si aucune erreur durant l'initialisation
            false sinon
     
      15/11/2006
    *************************************************************************/
    bool bootps::stopThreadServeur()
    {
    	//Fermer le socket serveur
    	erreur();	
     
    	cout << "Fermeture du thread..." << endl;
     
    	SetEvent(m_hEndThread);
     
    	// attend que le thread soit terminé
    	WaitForSingleObject(m_hWaitThread, INFINITE);
     
    	// fermeture dans handles
    	CloseHandle(m_hEndThread);
    	CloseHandle(m_hWaitThread);
     
    	//Termine la boucle infini du thread
    	//m_flagThread = false;
     
    	//Fermer le socket serveur
    	//erreur();	
     
    	return true;
    }
    Une partie du serveur, notamment l'appel à recvfrom et le moyen de stopper le thread:
    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
     
    while (true)
    {
    		// attente evenement de fin du thread. -> l'objet doit être ‘signalé ‘
    		// WaitForSingleObject  renvoie WAIT_OBJECT_0 si l'objet est signalé.
    		/*if(WaitForSingleObject(m_hEndThread, 0) == WAIT_OBJECT_0)
     
    		{
    			//Liberation des ressources
    			free((struct bootp *)bootp_recv); bootp_recv = NULL;
     
    			// signale l'objet event d'attente et sort.
    			SetEvent(m_hWaitThread);
    			return 0;
    		}*/
     
    		cod_ret = recvfrom(	bootps_socket,
    				(char*)bootp_recv,
    				BUFSIZ,
    				0,
    				(struct sockaddr *)NULL, (int *)NULL);
     
    		// attente evenement de fin du thread. -> l'objet doit être ‘signalé ‘
    		// WaitForSingleObject  renvoie WAIT_OBJECT_0 si l'objet est signalé.
    		if(WaitForSingleObject(m_hEndThread, 0) == WAIT_OBJECT_0)
     
    		{
    			//Liberation des ressources
    			free((struct bootp *)bootp_recv); bootp_recv = NULL;
     
    			// signale l'objet event d'attente et sort.
    			SetEvent(m_hWaitThread);
    			return 0;
    		}
     
    	... //code
    }
    Merci de vos suggestions ou corrections pour remédier à cela, je commence à sécher...

    Bonne soirée

    Nicolas

  2. #2
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Donc voici où j'ai placé la fonction erreur( comportant le closesocket() ) afin de debloquer le recvfrom() et de libérer les ressources suite à la validité de WaitForSingleObject():
    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
    /*************************************************************************
      stopThreadServeur: Stop le thread du serveur bootp.
     
      Valeur de retour:
    	true si aucune erreur durant l'initialisation
    	false sinon
     
      15/11/2006
    *************************************************************************/
    bool bootps::stopThreadServeur()
    {
    	SetEvent(m_hEndThread);
     
    	//Fermer le socket serveur
    	erreur();	
    
    	// attend que le thread soit terminé
    	WaitForSingleObject(m_hWaitThread, INFINITE);
     
    	return true;
    }
    Malgré cela, j'ai encore un plantage au moment de quitter l'appli...

    Voici les deux messages d'erreur qui arrivent successivement:
    le premier:
    Nom : Erreur.JPG
Affichages : 114
Taille : 18,3 Ko

    et le second:
    Nom : Erreur_suite.JPG
Affichages : 99
Taille : 21,7 Ko

    Ca pourra peut être aider!

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    La première signale qu'il y a eu un débordement de buffer, à un certain moment entre le new et le delete (bonne chance pour trouver)...
    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.

  4. #4
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Citation Envoyé par Mat.M
    Le programme console c'est client ou bien serveur ?.
    Cela semble être un problème de dépassement de pile ( dbgheap.c) ; les processus sont mal arrêtés ou bien des objets sont mal effacés
    Le programme console est serveur. A chaque adresse MAC que je recois, j'attribue une adresse IP definie selon un masque.
    Citation Envoyé par Medinoc
    La première signale qu'il y a eu un débordement de buffer, à un certain moment entre le new et le delete (bonne chance pour trouver)...
    Hum hum, interessant comme remarque. Cela peut être venir de mon buffer de reception dans le recvfrom...Du moins je pense.
    C'est clair que je me galère depuis plusieurs heures pour situer le problème.

    Bizarrement lorsque j'utilise le deuxième paramètre de recvfrom avec une structure déclarée statiquement (car je me dis que ca résoudrait le problème de libération des ressources), une erreur se produit au niveau de la réception. Ca devrait fonctionner je pense en principe.
    De souvenir quand j'ai essayé je crois que le transtypage en char* ne fonctionnait pas non plus...

    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
     
    struct bootp *bootp_recv = (struct bootp*)malloc(sizeof(struct bootp));
     
    while (true)
    {
    		cod_ret = recvfrom(	bootps_socket,
    				(char*)bootp_recv,
    				BUFSIZ,
    				0,
    				(struct sockaddr *)NULL, (int *)NULL);
     
    		// attente evenement de fin du thread. -> l'objet doit être ‘signalé ‘
    		// WaitForSingleObject  renvoie WAIT_OBJECT_0 si l'objet est signalé.
    		if(WaitForSingleObject(m_hEndThread, 0) == WAIT_OBJECT_0)
     
    		{
    			//Liberation des ressources
    			free((struct bootp *)bootp_recv); bootp_recv = NULL;
     
    			// signale l'objet event d'attente et sort.
    			SetEvent(m_hWaitThread);
    			return 0;
    		}
     
    	... //code
    }
    Voilà

    Bonne journée

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Es-tu sûr que ta structure "struct bootp" possède bien une taille de BUFSIZ ?
    D'ailleurs, BUFSIZ est une constante standard (ou POSIX), qui ne sert pour des buffers bien précis, il me semble...
    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
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Citation Envoyé par Medinoc
    Es-tu sûr que ta structure "struct bootp" possède bien une taille de BUFSIZ ?
    Avant de lire ton dernier message, j'ai fait ceci suite à ton précédent poste:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct bootp *bootp_recv = (struct bootp*)malloc(2*sizeof(struct bootp));
    Et à partir de ce moment, plus de soucis.

    En fait, sur le réseau, je ne recevais pas seulement des requêtes bootp mais aussi DHCP. Les reqêtes DHCP encapsulent le bootp donc possèdent une taille plus grande, d'ou le probleme de débordement de buffer comme tu m'as fait part et qui a fait tilt dans mon esprit!

    De plus, je ne suis pas sur que ma structure est de la taille de BUFSIZ, donc je vais vérifier cela maintenant.

    Surement qu'en faisant ceci, le problème serait réglé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct bootp *bootp_recv = (struct bootp*)malloc(sizeof(struct bootp));
    while (true)
    {
    		cod_ret = recvfrom(	bootps_socket,
    				(char*)bootp_recv,
    				sizeof(struct bootp),
    				0,
    				(struct sockaddr *)NULL, (int *)NULL);
    
       ...
    }
    En tout cas merci pour l'idée!

  7. #7
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut Fermeture thread: messages d'erreur
    Bonsoir,

    Je suis entrain de terminer un serveur bootp qui tourne dans un thread. Lorsque je désire terminer le thread, je ferme d'abord le sochet grâce à shutdown() puis closesocket() et j'utilise WaitForSingleObject() avec des "event" pour être bien sur que ce thread se termine avant le thread principal.

    Lorsque la console se ferme, j'ai deux messages qui apparaissent successivement, quelles pourraient en être les causes car j'ai du mal à cerner où je me plante dans mon code:

    Le premier:
    Nom : Erreur.JPG
Affichages : 103
Taille : 18,3 Ko

    Le second:
    Nom : Erreur_suite.JPG
Affichages : 116
Taille : 21,7 Ko

    Merci.
    Bonne soirée

  8. #8
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 527
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 527
    Par défaut
    Le programme console c'est client ou bien serveur ?.
    Cela semble être un problème de dépassement de pile ( dbgheap.c) ; les processus sont mal arrêtés ou bien des objets sont mal effacés

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

Discussions similaires

  1. [Thread] Stopper un thread pendant que les autres tournent
    Par NutellaPiou dans le forum Concurrence et multi-thread
    Réponses: 13
    Dernier message: 30/01/2009, 11h45
  2. [thread] Stopper un thread
    Par poukill dans le forum Threads & Processus
    Réponses: 6
    Dernier message: 04/12/2008, 17h34
  3. Fermeture de thread impossible
    Par cbegood dans le forum Windows Forms
    Réponses: 2
    Dernier message: 13/10/2008, 10h28
  4. Fermeture de thread
    Par Racailloux dans le forum MFC
    Réponses: 7
    Dernier message: 07/08/2007, 14h26
  5. [Thread] Stopper l'exécution d'un thread brutalement
    Par Razgriz dans le forum Concurrence et multi-thread
    Réponses: 7
    Dernier message: 31/01/2007, 19h55

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