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 :

Synchronisation de deux threads.


Sujet :

Threads & Processus C++

  1. #1
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut Synchronisation de deux threads.
    Bonsoir.
    Apres avoir fait une tentative sur le chat, je me redirige vers le forum !

    Pour commencer, je vais mettre un peux l'ambiance:
    1>------ Début de la génération*: Projet*: XServer, Configuration*: Debug Win32 ------
    1>La génération a démarré 19/11/2011 03:01:53.
    1>InitializeBuildStatus:
    1> Mise à jour de l'horodatage "Debug\XServer.unsuccessfulbuild".
    1>ClCompile:
    1> PacketManager.cpp
    1> Génération de code en cours...
    1> Compilation en cours...
    1> Threads.cpp
    1>Threads.cpp(57): warning C4018: '>'*: incompatibilité signed/unsigned
    1> Génération de code en cours...
    1> Ignoré... (aucune modification pertinente détectée)
    1> Database.cpp
    1> WorldServer.cpp
    1> Tools.cpp
    1> Server.cpp
    1> Packet.cpp
    1> LoginServer.cpp
    1> ClientManager.cpp
    1>ManifestResourceCompile:
    1> Toutes les sorties sont à jour.
    1>LoginServer.obj : error LNK2005: "class Mutexx * WSP" (?WSP@@3PAVMutexx@@A) déjà défini(e) dans ClientManager.obj
    1>LoginServer.obj : error LNK2005: "struct XServer:acketQueue WorldServerPackets" (?WorldServerPackets@@3UPacketQueue@XServer@@A) déjà défini(e) dans ClientManager.obj
    1>Packet.obj : error LNK2005: "class Mutexx * WSP" (?WSP@@3PAVMutexx@@A) déjà défini(e) dans ClientManager.obj
    1>Packet.obj : error LNK2005: "struct XServer:acketQueue WorldServerPackets" (?WorldServerPackets@@3UPacketQueue@XServer@@A) déjà défini(e) dans ClientManager.obj
    1>PacketManager.obj : error LNK2005: "class Mutexx * WSP" (?WSP@@3PAVMutexx@@A) déjà défini(e) dans ClientManager.obj
    1>PacketManager.obj : error LNK2005: "struct XServer:acketQueue WorldServerPackets" (?WorldServerPackets@@3UPacketQueue@XServer@@A) déjà défini(e) dans ClientManager.obj
    1>Server.obj : error LNK2005: "class Mutexx * WSP" (?WSP@@3PAVMutexx@@A) déjà défini(e) dans ClientManager.obj
    1>Server.obj : error LNK2005: "struct XServer:acketQueue WorldServerPackets" (?WorldServerPackets@@3UPacketQueue@XServer@@A) déjà défini(e) dans ClientManager.obj
    1>Threads.obj : error LNK2005: "class Mutexx * WSP" (?WSP@@3PAVMutexx@@A) déjà défini(e) dans ClientManager.obj
    1>Threads.obj : error LNK2005: "struct XServer:acketQueue WorldServerPackets" (?WorldServerPackets@@3UPacketQueue@XServer@@A) déjà défini(e) dans ClientManager.obj
    1>Tools.obj : error LNK2005: "class Mutexx * WSP" (?WSP@@3PAVMutexx@@A) déjà défini(e) dans ClientManager.obj
    1>Tools.obj : error LNK2005: "struct XServer:acketQueue WorldServerPackets" (?WorldServerPackets@@3UPacketQueue@XServer@@A) déjà défini(e) dans ClientManager.obj
    1>WorldServer.obj : error LNK2005: "class Mutexx * WSP" (?WSP@@3PAVMutexx@@A) déjà défini(e) dans ClientManager.obj
    1>WorldServer.obj : error LNK2005: "struct XServer:acketQueue WorldServerPackets" (?WorldServerPackets@@3UPacketQueue@XServer@@A) déjà défini(e) dans ClientManager.obj
    1>C:\Users\nico\Documents\Visual Studio 2010\Projects\game\Debug\XServer.exe : fatal error LNK1169: un ou plusieurs symboles définis à différentes reprises ont été rencontrés
    1>
    1>ÉCHEC de la build.
    1>
    1>Temps écoulé 00:00:08.29
    ========== Génération*: 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========
    Ceci fait, voici également le projet intégral (Oui, c'est la continuité de mes anciens sujets, mais j'ai tellement modifié de choses que j'ai fermé les anciens !)

    http://chat.developpez.com/upload/5d...5ce795f082.zip


    ---------------------------------------------
    NB Avant de répondre:
    - Oui mon code est etrange (tout les headers rassemblés dans includes.h)
    - Toutes les erreurs d'écriture du c++ ont ete signalées sur le chat, je n'ai pas besoin d'un rappel ! Mais merci
    ---------------------------------------------


    Le problème:
    Je viens de copier coller ceci: http://leetnightshade.com/archives/231
    Dans mon projet, (nom changé!) et a partir de ce moment là, mon projet ne compile plus (cf: erreurs au début du sujet !)
    Ce que je cherche à faire:
    Quand mon serveur recoit un packet (Threads.cpp > ligne 77 à 95) il le transmet de cette facon pm->handlePacket(packet); à la classe PacketManager.
    Ensuite cette classe, va lire le premier byte du packet (PacketManager.cpp > ligne 17 & 32), et en fonction de ca valeur approximate, va renvoyer le packet dans (ce que vous avez, il y a juste WorldServerPackets.Packets.push(Packet);)
    Evidemment, j'ai executé un Lock juste avant pour proteger WorldServerPackets.

    -Pourquoi- ?
    Une fois balancé dans cette queue, le thread WorldServerT (Threads.cpp) va tenter de lire la queue () WorldServerPackets. Si il y a des Packets dedans, hopla, le code continue.


    Maintenant, pourquoi VS est-il faché contre mon code, ou plus précisément, contre cette nouvelle classe?
    Il détecte les copier/coller maintenant ?

    Un grand merci d'avance à celui qui arrivera à résoudre le problème.

  2. #2
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Bonjour,

    Dans le fichier WorldServer.h tu as cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Mutexx* WSP = new Mutexx();
    C'est une définition, elle devrait être dans un fichier source, sinon comme le fichier est inclue plusieurs fois elle se retrouve dans plusieurs fichiers sources et tu as donc un problème de définition multiple.

    Dans ce fichier tu peux avoir une déclaration si tu en as besoin (extern).

  3. #3
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut
    Bonjour !

    Je ne vois pas l'interet d'utiliser extern, apparement il sert à ce que ma variable WSP soit visible dans tout le programme.
    Or, elle est déclarée en dehors de la classe, pour que justement, elle soit visible !
    donc ??
    De plus, en changeant WorldServer.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    extern Mutexx* WSP;
    extern XServer::PacketQueue WorldServerPackets;
    Et WorldServer.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    XServer::WorldServer::WorldServer() { 
    // [...]
    WSP =new Mutexx();
    // [...]
    }
    J'obtient ceci:
    1>------ Début de la génération*: Projet*: XServer, Configuration*: Debug Win32 ------
    1>La génération a démarré 19/11/2011 13:58:23.
    1>InitializeBuildStatus:
    1> Mise à jour de l'horodatage "Debug\XServer.unsuccessfulbuild".
    1>ClCompile:
    1> Toutes les sorties sont à jour.
    1>ManifestResourceCompile:
    1> Toutes les sorties sont à jour.
    1>PacketManager.obj : error LNK2001: symbole externe non résolu "struct XServer:acketQueue WorldServerPackets" (?WorldServerPackets@@3UPacketQueue@XServer@@A)
    1>Threads.obj : error LNK2019: symbole externe non résolu "struct XServer:acketQueue WorldServerPackets" (?WorldServerPackets@@3UPacketQueue@XServer@@A) référencé dans la fonction "unsigned long __stdcall ls_Listen(void *)" (?ls_Listen@@YGKPAX@Z)
    1>PacketManager.obj : error LNK2001: symbole externe non résolu "class Mutexx * WSP" (?WSP@@3PAVMutexx@@A)
    1>Threads.obj : error LNK2019: symbole externe non résolu "class Mutexx * WSP" (?WSP@@3PAVMutexx@@A) référencé dans la fonction "unsigned long __stdcall ls_Listen(void *)" (?ls_Listen@@YGKPAX@Z)
    1>WorldServer.obj : error LNK2001: symbole externe non résolu "class Mutexx * WSP" (?WSP@@3PAVMutexx@@A)
    1>C:\Users\nico\Documents\Visual Studio 2010\Projects\game\Debug\XServer.exe : fatal error LNK1120: 2 externes non résolus
    1>
    1>ÉCHEC de la build.
    1>
    1>Temps écoulé 00:00:01.17
    ========== Génération*: 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========

  4. #4
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    extern ca veut dire que tu déclares cette variable, sans ca tu la définies, et comme le fichier est inclue plusieurs fois elle se retrouve définie plusieurs fois, ce qui est interdit (par contre on peut la déclarer plusieurs fois).

    Tu as oublié de définir WorldServerPackets dans ton fichier de définition (comme Mutexx dans le .cpp) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    XServer::PacketQueue WorldServerPackets;
    Edit: Et vires ton histoire de fichier d'inclusion globale, sinon tu vas finir par avoir une erreur qui sera difficile à localiser.

  5. #5
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut
    Je peux mettre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Mutexx* WSP;
    XServer::PacketQueue WorldServerPackets;
    n'importe où, j'ai toujours une erreur de link...
    Je comprend pas d'où ca vient !?

  6. #6
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    WorldServer.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include "includes.h"
     
    Mutexx* WSP = new Mutexx();
    XServer::PacketQueue WorldServerPackets;
     
    XServer::WorldServer::WorldServer() { }
    XServer::WorldServer::~WorldServer() { }
    WorldServer.h
    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
     
    #ifndef H_WORLDSERVER
    #define H_WORLDSERVER
     
    #define WS_MAX_CLIENTS		50
    #define WS_CHANNELS			1
     
    extern Mutexx* WSP;
    extern XServer::PacketQueue WorldServerPackets;
     
    namespace XServer {
    	class WorldServer {
    	public:
    		HANDLE		thread;
    		//HANDLE		Rthread;
    		static void Start();
    		static void Shutdown();
    		bool acceptingClients() { return _acceptClients; };
    		int getMaxClients() { return WS_MAX_CLIENTS; };
    		int nbClients() { return _nbClients; };
    		int getChannels() { return _nbChannels; }
    	private:
    		bool _acceptClients;
    		int _nbClients;
    		int _nbChannels;
    		WorldServer();
    		~WorldServer();
    		static WorldServer *instance;
    	};
    };
    #endif
    Pour l'origine, c'est lié à l'ODR (one definition rules), que j'ai expliqué dans mes messages précédents (plusieurs déclaration de tes variables dans le programmes, mais une seule définition).

  7. #7
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut
    C'est pas possible comment vous faites pour savoir ca !
    Eh bien merci, J'aurais juste une derniere question

    Pourquoi mettre extern XServer:acketQueue WorldServerPackets; dans le .h si apres on remet XServer:acketQueue WorldServerPackets; dans le .cpp ? Ca sert a quoi ?

  8. #8
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Quant tu compiles ton programme, chaque fichier source (.cpp) est compilé. Quand on utilise une variable dans ce fichier il faut qu'elle ai été au moins déclarée avant, c'est à ca que sert les deux lignes avec extern dans le fichier de déclaration (.h). Ensuite il y a une étape d'édition des liens qui regroupe l'ensemble des fichiers issues de la compilation des différents fichier sources (.cpp). A ce moment il faut que toutes les variables ai été définie une et une seul fois, c'est à ca que servent les deux lignes dans le fichier source (.cpp), si on les mets dans un fichier de déclaration (.h) comme tu l'as fait au début, elles se retrouvent définies dans plusieurs fichiers objet (ceux issues de la compilation des différents fichiers sources), d'où tes erreurs.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/10/2013, 23h39
  2. Synchroniser correctement deux threads
    Par supcomingenieur dans le forum Général Java
    Réponses: 13
    Dernier message: 16/04/2013, 15h46
  3. Réponses: 1
    Dernier message: 23/03/2013, 22h21
  4. Réponses: 6
    Dernier message: 13/09/2010, 16h02
  5. synchronisation entre deux threads
    Par chabfive dans le forum Concurrence et multi-thread
    Réponses: 9
    Dernier message: 03/11/2006, 12h17

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