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

MFC Discussion :

[MFC] CArchive dans une thread


Sujet :

MFC

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 77
    Points : 46
    Points
    46
    Par défaut [MFC] CArchive dans une thread
    Bonjour tout le monde ^^


    J'aimerais savoir si ça peut poser des problèmes d'utiliser une CArchive dans une thread car lorsque j'en utilise une dans mon programme principal je n'ai aucun problème, mais lorsque je la mets dans une thread, j'ai une assertion failed en exécution.


    Quelqu'un a déjà eu un problème similaire? Je pense que mes déclarations sont correctes et je n'arrive pas à cerner le problème...


    Merci d'avance ^^

    (si mes explications ne sont pas claires, dites-le, je préfère réexpliquer que rester sans réponse ^^")

  2. #2
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    ça ne devrait pas causer de probleme .
    par contre c'est peut etre les données a archivées qui peuvent causer un probleme.(les moyens mis en oeuvre pour y acceder) .
    sans voir un brin de code et sans details sur le contexte on peut rien dire de plus.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 77
    Points : 46
    Points
    46
    Par défaut
    J'attendais de voir si quelqu'un avait une idée de ce que ça pouvait être avant d'inonder de code

    Le principe est que dans le programme principal, lorsqu'on appelle une fonction Send(), je mets dans une FIFO les éléments à envoyer.
    Et dans une thread, je récupère ce qu'il y a dans la FIFO et je l'envois sur le réseau grâce à une archive.

    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
    UINT Connection::ThreadsSend()
    {
    	TRACE("Thread Send\n");
    	while(true)
    	{
    		WaitForSingleObject(wait_send, INFINITE);
    		TRACE("WaitForSingleObject : wait_send\n");
    		if(FIFOimage.GetRemSizeR() == 0)
    		{
    			// Il n'y en a pas! La FIFO est donc vide. Il faut attendre que la thread d'écriture 
    			// place un élément dans cette FIFO...
     
    			TRACE("FIFO EMPTY!\n");
    			WaitForSingleObject(wait_send, INFINITE);
    		} else
    		{
    			strcpy(MyArguments.structHeader.name,"Name");
    			MyArguments.structHeader.numfct = 1;
    			size = 10000;
    			TRACE("Thread Send : %s et %d | size = %d\n",MyArguments.structHeader.name, MyArguments.structHeader.numfct,size);
    			BYTE* jpeg2 = NULL;
    			DWORD size = 0;
    			TRACE("Avant le read %s\n",jpeg2);
    			FIFOimage.Read(MyArguments, size, jpeg2);
    			TRACE("Après le read %s\n",jpeg2);
    			char*jpeg = new char[size];
    			strcpy(jpeg,(const char*)jpeg2);
    			TRACE("Avant l'archive %s et size = %d\n",jpeg, size);
    			TRACE("(sock = %.8x) New : m_pFile -> %.8x | m_pArIn -> %.8x | m_pArOut -> %.8x |\n", incomingSock, m_pFile,m_pArIn,m_pArOut);
    			m_pArOut->Write(jpeg, 10);
    			TRACE("Après le write\n");
    			m_pArOut->Flush();
    			TRACE("Après l'archive\n");
    			FIFOimage.UpdatePtrR();
    		}
    		SetEvent(wait_receive);
    	}
    	return 0;
    }
    J'ai mis des trace un peu partout et la dernière que je vois est celle avant l'archive.
    Les pointeurs sont identiques dans la thread principale et celle-là, tout à l'air d'être initialisé, je ne vois vraiment pas où est le problème (je suis un peu nulle j'avoue mais bon ^^")
    Acutellement je ne fais pas travailler l'archive avec la FIFO puisque j'essaie de voir quel est le problème donc j'essaie bêtement de mettre du texte dans l'archive mais ça ne fonctionne pas...

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    un truc me chiffone dans ton code ,
    la fonction de thread doit etre statique a la classe ,dans ce contexte comment se fait il que tu accedes a des données membres comme m_pArOut etc...
    a moins que tu n'ais redirigé sur une fonction de l'instance a partir de la fonction du thread ...
    autrement cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    FIFOimage.Read(MyArguments, size, jpeg2);
    jpeg2 est null c'est normal ça ?


  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 77
    Points : 46
    Points
    46
    Par défaut
    Bah normalement, justement, après ce READ, il ne l'est plus.

    En fait c'est une thread spéciale, c'est mon maitre de stage qui m'a montré "ce truc" :


    Thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UINT Connection::ThreadsSend(LPVOID pthis)
    {
    	Connection *me = static_cast<Connection*>(pthis);
    	return me->ThreadsSend();
    }
    Fonction où va la 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
    38
    39
    UINT Connection::ThreadsSend()
    {
    	TRACE("Thread Send\n");
    	while(true)
    	{
    		WaitForSingleObject(wait_send, INFINITE);
    		TRACE("WaitForSingleObject : wait_send\n");
    		if(FIFOimage.GetRemSizeR() == 0)
    		{
    			// Il n'y en a pas! La FIFO est donc vide. Il faut attendre que la thread d'écriture 
    			// place un élément dans cette FIFO...
     
    			TRACE("FIFO EMPTY!\n");
    			WaitForSingleObject(wait_send, INFINITE);
    		} else
    		{
    			strcpy(MyArguments.structHeader.name,"Name");
    			MyArguments.structHeader.numfct = 1;
    			size = 10000;
    			TRACE("Thread Send : %s et %d | size = %d\n",MyArguments.structHeader.name, MyArguments.structHeader.numfct,size);
    			BYTE* jpeg2 = NULL;
    			DWORD size = 0;
    			TRACE("Avant le read %s\n",jpeg2);
    			FIFOimage.Read(MyArguments, size, jpeg2);
    			TRACE("Après le read %s\n",jpeg2);
    			char*jpeg = new char[size];
    			strcpy(jpeg,(const char*)jpeg2);
    			TRACE("Avant l'archive %s et size = %d\n",jpeg, size);
    			TRACE("(sock = %.8x) New : m_pFile -> %.8x | m_pArIn -> %.8x | m_pArOut -> %.8x |\n", incomingSock, m_pFile,m_pArIn,m_pArOut);
    			m_pArOut->Write(jpeg, 10);
    			TRACE("Après le write\n");
    			m_pArOut->Flush();
    			TRACE("Après l'archive\n");
    			FIFOimage.UpdatePtrR();
    		}
    		SetEvent(wait_receive);
    	}
    	return 0;
    }
    Résultat des TRACE :
    WaitForSingleObject : wait_send
    Thread Send : Name et 1 | size = 10000
    Avant le read (null)
    Après le read Thread
    Avant l'archive Thread et size = 18249
    (sock = 002f5270) New : m_pFile -> 002f82b0 | m_pArIn -> 002f8308 | m_pArOut -> 002f93d8 |


    Et le compilateur m'amène sur ces lignes lorsque je clique sur réessayer au lieu de abandonner :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void CAsyncSocket::AssertValid() const
    {
    	CObject::AssertValid();
    	ASSERT(m_hSocket == INVALID_SOCKET || CAsyncSocket::FromHandle(m_hSocket) != NULL);
    }

  6. #6
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    bon pour le point ok c'est ce que je pensais ...
    un detail se code me semble suspect:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char*jpeg = new char[size]; 
    strcpy(jpeg,(const char*)jpeg2);
    strcpy copie la zone sur la longueur + le zero .
    reste a savoir si size comprend le zero ou non ....
    si c'st pas le cas tu as un debordement memoire de 1 octet ,qui peut expliquer le probleme qui suit ...

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 77
    Points : 46
    Points
    46
    Par défaut
    Je ne sais pas, pcq quand j'essaie avec la structure MyArguments, ça ne fonctionne pas non plus (alors que si je mets ce code tel quel dans le thread principal, il fonctionne)

    Et je viens d'essayer en mettant size+1 mais ça plante tjrs

  8. #8
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    ça n'est pas suffisant les bugs de memoire (debordements etc) peuvent se reveler juste en changeant de contexte .
    le probleme est de savoir si tu debordes en memoire ou non ..
    si tu mets le strcpy(jpeg,(const char*)jpeg2); entre commentaire le write passe ?

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 77
    Points : 46
    Points
    46
    Par défaut
    Non, ça ne passe toujours pas.

    Je suis vraiment désolée, je suis pas douée ^^"

  10. #10
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    il faut que tu nous donnes le detail de l'assertion d'erreur ....

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 77
    Points : 46
    Points
    46
    Par défaut
    Comme je le disais plus haut (j'ai édité pendant que tu postais apparement ^^"), mon erreur m'amène là dans le fichier sockcore.cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void CAsyncSocket::AssertValid() const
    {
    	CObject::AssertValid();
    	ASSERT(m_hSocket == INVALID_SOCKET || CAsyncSocket::FromHandle(m_hSocket) != NULL);
    }

    Mais je viens de trouver un article en anglais et apparement, il faudrait détacher le handle du socket avant de rentrer dans la thread, et le rattacher après. Ca parait plausible?


    EDIT :

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_wcemfc4/html/aflrfCSocketcolcolAttach.asp
    http://support.microsoft.com/default.aspx?scid=kb;EN-US;175668

    Apparement comme ça, ça a l'air de fonctionner, ça ne me plante plus en exécution mais du coup, il ne veut pas faire de close sur mon socket, j'ai pas du tout l'habitude d'utiliser les handle de socket :/

  12. #12
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    oui c'est sur que c'est ça ton pb ,
    le probleme c'est les sockets utilisent une notification des messages par l'intermediaire d'une fenetre windows.
    et quand dans le cas d'un workerthread c'sst le travail avec des objets graphiques qui cause un probleme.
    voir faq: http://c.developpez.com/faq/vc/?page...d#WorkerThread

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 77
    Points : 46
    Points
    46
    Par défaut
    Erf ok, merci beaucoup ^^

    Faut que j'arrive à régler les autres problèmes maintenant >.>

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

Discussions similaires

  1. [MFC] Dessin dans une boite de dialogue .
    Par Platypus dans le forum MFC
    Réponses: 8
    Dernier message: 21/07/2005, 11h21
  2. [MFC] CTabCtrl dans une CDialog
    Par eyghon dans le forum MFC
    Réponses: 1
    Dernier message: 29/04/2005, 19h31
  3. [mfc] affichage dans une boite de dialog
    Par chronos dans le forum MFC
    Réponses: 3
    Dernier message: 14/06/2004, 15h12
  4. [MFC] Dialog dans une boucle while
    Par oxor3 dans le forum MFC
    Réponses: 5
    Dernier message: 23/04/2004, 22h51
  5. [MFC] CPropertySheet dans une CFormView ???
    Par Lofwyr dans le forum MFC
    Réponses: 2
    Dernier message: 30/07/2003, 16h49

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