2011-01-04 6 views
1

Im implémentant une application de chat en utilisant Jabber/XMPP et gloox framework qui devraient envoyer et recevoir des messages simultanément sous Ubuntu Linux.Multithreading pour la fonction de rappel en C++

Ma mise en œuvre actuelle de code est:

int main() 
{ 
     ... 
int temp = pthread_create(&iSend, NULL, SendMessage, &b); 
int temp1 = pthread_create(&iRecv, NULL, ConnServer, &b); 
} 

void* ConnServer(void *athis) 
{ 
UserClient *t = (UserClient*)athis; 
t->ConnecttosServer(); 
} 

bool UserClient::ConnecttosServer() 
{ 
//JID jid("[email protected]/gloox"); 

j = new Client(iUserJid, iUser.getPassword()); 
j->registerMessageHandler(this); 
j->registerConnectionListener(this); 
j->registerMessageSessionHandler(this); 
bool result = j->connect(false); 
if(result == true) 
{ 
    iConnected = true; 
    ConnectionError er = ConnNoError; 
    ConnectionError er1 = ConnNoError; 
    while(er == ConnNoError || er1 == ConnNoError) 
    { 
    er = j->recv(500000); 
    sleep(2); 
    } 
    delete j; 
} 
... 
} 

void* SendMessage(void * athis)// JID *aDest) 
{ 
UserClient *t = (UserClient*)athis; 
//JID *t = (JID)dest; 

string ip ; 
cout << "enter here"; 
cin >> ip; 
if(t->iConnected == true) 
{ 
    if(t->iMessageSession == NULL) 
    { 
    string aBody = "hello"; 

    MessageSession *session = new MessageSession(t->j, t->iDestJid); 
    session->registerMessageHandler(t); 
    session->send(aBody.c_str()); 
    } 
} 
} 

Le problème rencontré est à la fois les fils sont créés et pthread_join() est appelé pour les deux.

L'unité d'exécution iSend est programmée en premier, mais elle est suspendue à l'état cin. Une fois la fonction recv() appelée, qui s'exécute dans le thread iRecv, la fonction d'appel recv handleMessage() est appelée. Cependant, le contrôle ne revient jamais sur le thread iSend qui devrait appeler la fonction SendMessage().

S'il vous plaît aider

+0

Question rapide - vous effectuez un appel de connexion et envoyez un message simultanément - pouvez-vous le faire ou devriez-vous les appeler en série? En outre, le cin suspend parce qu'il attend un caractère de stdin. Pouvez-vous taper quelque chose? –

+0

Outre tous vos autres problèmes techniques ici (par exemple, les fuites de mémoire), vous appelez 'j-> recv (500000)'. Si la mémoire est utilisée, elle bloquera jusqu'à ce qu'elle reçoive le nombre d'octets requis dans la taille de la mémoire tampon (500 000 dans ce cas). Puisque je doute que vous envoyez autant de données avec ce programme simple, je suggérerais d'en faire un tampon beaucoup plus petit pour commencer et de l'augmenter seulement si vous voyez le besoin de le faire. –

+0

Envoyer et Recv ne se produisent pas simultanément. J'ai aussi commenté cin, mais cela n'a pas changé le comportement. La fonction SendMessage n'est pas planifiée du tout .. – user562701

Répondre

0

Je ne vois pas là comment SendMessage envoie de plus en plus d'un message « bonjour ».

Il y a bien sûr plusieurs problèmes de mémoire, par exemple, j ne sera pas supprimé du tout si la connexion échoue, et comme sa portée est uniquement fonctionnelle, il n'est pas vraiment nécessaire de la créer.

+0

salut, c'est mon doute exact. Je dois obtenir l'entrée de l'utilisateur en utilisant cin et plus sur le thread d'iSend devrait être programmé parallèlement avec thread iRecv qui gère la fonction de rappel. – user562701

0

Vous ne pouvez pas compter sur l'unité d'exécution iSend programmée en premier. C'est complètement à la hauteur du système d'exploitation.