Probleme thread

Signaler
Messages postés
117
Date d'inscription
mardi 3 février 2004
Statut
Membre
Dernière intervention
24 avril 2006
-
Messages postés
12
Date d'inscription
jeudi 19 novembre 2009
Statut
Membre
Dernière intervention
1 décembre 2010
-
J'ai un probleme avec les thread
J,ai un server et jessai de créer un thread a chaque fois quun client se connecte, mais sa fonctionne pas.

J,ai essayer avec CreateThread et _beginthread et j'ai la meme erreur

voici mon code

c une classe server

CServer::CServer()
{
initialisation des variable et socket....
}

CServer::~CServer()
{

}

void CServer::start()
{
socket = accept(......)

//J,ai essayé avec create thread
HANDLE hThread;
DWORD dwThreadId;

hThread = CreateThread(NULL, 0, nouveauClient, (void*)socket, 0, &dwThreadId);

//et avec beginthread (pas les deux en meme temps la)

_beginthread(nouveauClient, 0, (void*)socket);
}

//Je veux envoyer en parametre le socket du nouveau client
void CServer::nouveauClient(void* socket)
{
int sock = (int)socket;

.............

}

Lerreur que jai est la suivante
avec beginthread
error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)'
None of the functions with this name in scope match the target type

avec CreateThread
error C2664: 'CreateThread' : cannot convert parameter 3 from 'void (void *)' to 'unsigned long (__stdcall *)(void *)'
None of the functions with this name in scope match the target type

J,ai essayer en faisant un thread de la meme facon mais juste dans un main avec une fonction et sa fonctiopnne.....on dirais que cest quand je le mest dans une classse que sa fonctionnevpas

quelqun peu maider???

classmulti.exe - 2 error(s), 0 warning(s)

9 réponses

Messages postés
2676
Date d'inscription
vendredi 28 juin 2002
Statut
Membre
Dernière intervention
13 janvier 2016
16
salut

ta fonction void CServer::nouveauClient(void* socket) ne respecte pas le type de fonction attendue par CreateThread ou _beginthread (d'après l'erreur de compilo):
il faut qu'elle soit :

unsigned long _stdcall CServer::nouveauClient(void* socket) //pour CreateThread

void _cdecl CServer::nouveauClient(void* socket) //pour _beginthread

cela dit, je ne suis pas sur que ca marche avec des méthodes...

ShareVB
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
la fonction à opasser à CreateThread doit être ststic dans la classe. au besoin passer un pointeur this pendant la création.
Messages postés
117
Date d'inscription
mardi 3 février 2004
Statut
Membre
Dernière intervention
24 avril 2006

Je comprend pas se que tu veux dire par au besoin passe un pointeur this ????

Si il faut que ma méthode soit static, je vois pu lutilité de me faire une classe, je peut meme pas avoir acces au autres méthode dsans ma class nis au variable ....comment je fais pour avoir acces au méthode ???
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
en donnant un pointeur this de l'objet créant le thread à la ThreadProc :

// Méthode non static
void CServer::start()
{
// création thread
DWORD dwTID;
CreateThread(NULL, 0 CServer::ThreadProc, this, 0, &dwTID);
}

// méthode static
DWORD WINAPI CServer::ThreadProc( LPVOID lpParameter)
{
// récupération objet CServer pour accès aux fct membres.
CServer* pObj = (CServer*)lpParameter;
return 0;
}

=> le thread à comme paramètre l'objet CServer qui l'a créer et peut accéder à ses membres.
Messages postés
117
Date d'inscription
mardi 3 février 2004
Statut
Membre
Dernière intervention
24 avril 2006

Merci sa fonctionne!!

Mais est-ce que c'Est une bonne facon de faire d'utiliser un pointeur this pour avoir acces au membre de la classe???
Et vu que la méthode est static....est ce que sa va fonctioner meme si je lappelle plusieurs....(je crée plusieurs thread avec ) ???? et si jai plusieur objet CServer par exemple....est-ce que sa va etre la meme méthode pour chaque objet ??? comme une variable static...??

Et pk mets tu DWORD WINAPI avec la méthode ????
moi je l'ai applé static void...est-ce la meme chose ??? quelle est la différence ???

Merci
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
"Mais est-ce que c'Est une bonne facon de faire d'utiliser un pointeur this pour avoir acces au membre de la classe???"

=> toutes les fct membres ont un paramètres implicite this qui est l'objet sur lequel porte la méthode. Il n'y a donc aucun problème pour passer ce pointeur à une autre fonction qui va s'en servir pour accéder aux membres (que cette fct soit ou non dans la même classe).

"Et vu que la méthode est static....est ce que sa va fonctioner meme si je lappelle plusieurs....(je crée plusieurs thread avec ) ???? et si jai plusieur objet CServer par exemple....est-ce que sa va etre la meme méthode pour chaque objet ??? comme une variable static...??"

= >Le point d'entré du thread est static (appeler pour tous les threads) mais comme il y a en paramètre un pointeur sur l'objet CServer associé, rien ne t'empèche d'appeler une autre fct membre non static nouveauClient. Ainsi le thread est spécialisé sur l'objet qui l'a crée

"Et pk mets tu DWORD WINAPI avec la méthode ????"
=> c'est le prototype de la fonction a passer à CreateThread (cf MSDN :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/threadproc.asp
Messages postés
117
Date d'inscription
mardi 3 février 2004
Statut
Membre
Dernière intervention
24 avril 2006

Merci beaucoup, sa fonctionne!!

Mais j'aurais une dernière question.
J,ai parti mon thread dans lequel le serveur fais un accept et attend qu'un client se connecte, mais je voudrais savoir comment faire pour arreté le thread?? car la fonction accept est bloquante alors quand je fais ExitThread sa ne fonctionne pas pcq il attend que accept soit fini....il y a til un moyen de terminer le thread sans utiliser TerminateThread qui n'est pas tres bon car elle ne désalloué pas la mémoire...

Merci!!!!
Messages postés
2070
Date d'inscription
mardi 22 avril 2003
Statut
Membre
Dernière intervention
3 juillet 2006
8
si le thread est bloqué, il n'y a pas d'autres solutions que TerminateThread ou alors il faut un moyen pour que ta fct "accept" rende la main au thread pour qu'il sorte de sa fct ThreadProc...
Messages postés
12
Date d'inscription
jeudi 19 novembre 2009
Statut
Membre
Dernière intervention
1 décembre 2010

nice
Bonjour tr le monde ,

en faite je suis entrain de programmer une ptite application multithread qui envoie des sockets à des @ IP(10 @ en simultané) et selon le retour de select de socket il decode l'entete(IpHeader) et revoi le resultat ; si on teste la select avec un seul poste en simultané il marche trés biens alors que lorsque je tente de le testé avec plus que de 2 en simultanés la select retourne toujours 1 = sig que la select contient des donnees alors ce n est pas le cas ! (car ces adresses IP ne sont pas connectés ) !
voila un extrait de code :

// Initialisation du nombre de ping à faire = nombre de retrait
if(iNBPing == 0)
iNBPing = NBPINGDEFAULT;//si le nombre de retarit est a 0 on prend le nombre par default 1.

// Initialisation du délai d'attente
if(iTpsLimite == 0)
iTpsLimite = DEFALUTTIMEOUT;//si le delai d'attente est 0 on prend le timeout par defaut 1000 MS

while((CHote->iNbRetryUsed != iNBPing)&&(!bRstConn))
{
memset(szICMP_data,0,DATASIZE_ICMP);
iID = (unsigned short)GetCurrentProcessId() + CHote->iNbRetryUsed;
// Construction du paquet ICMP
IcmpHeader *icmp_hdr;
icmp_hdr = (IcmpHeader*)szICMP_data;
icmp_hdr->type = TYPE_ICMP_ECHO; // Type du paquet ICMP : echo request
icmp_hdr->code = CODE_ICMP_NULL; // Il n'y a pas de code spécifique pour ce type de paquet
icmp_hdr->id = iID;//identificateur de paquet
icmp_hdr->sequence = SEQU_ICMP_ECHO;
icmp_hdr->timestamp = GetTickCount(); // Initialisation du temps lors de l'envoi

// Somme de contrôle sur 16 bits
((IcmpHeader*)szICMP_data)->checksum = checksum((unsigned short*)szICMP_data, DATASIZE_ICMP);

// On envoie le paquet ICMP que l'on a construit
iEnvoi = sendto(sock, szICMP_data, DATASIZE_ICMP, 0, (struct sockaddr *)&sin, DATASIZE_ICMP);
FD_ZERO(&fdsr);
FD_SET(sock, &fdsr);

tv_timeout.tv_sec = iTpsLimite/1000;
tv_timeout.tv_usec = 0;


iFindelai = 0;

do{
if (select(sock+1, &fdsr, NULL, NULL, &tv_timeout) <= 0)
{
// Dans le cas où le temps est écoulé, on veut sortir de la boucle
// on compte le paquet comme envoyé mais perdu
// delai d'attente de la demande depassée
CHote->iNbRetryUsed = CHote->iNbRetryUsed+1;
iPerte= iPerte+1;
iFindelai = 1;

}

//Cette fonction vérifie si le descripteur "sock" est contenu dans l'ensemble "fdsr" après l'appel à select.
if (FD_ISSET(sock, &fdsr))
{
// Dans le cas où le buffer du socket contient des données,
// on les décode
iRecept=recvfrom(sock, szRecvbuf, MAX_PACKET, 0, (struct sockaddr *)&from, &iFromlen);

/***********************************************************/
iphdr = (IpHeader *)szRecvbuf;
iphdrlen = iphdr->h_len * 4 ;
icmphdr = (IcmpHeader*)(szRecvbuf + iphdrlen);

if(iID!=(icmphdr->id))
{
// Cas où le paquet n'est pas à nous
iFindelai= 0;
}
else
{
CHote->iNbRetryUsed = CHote->iNbRetryUsed +1;
iFindelai= 1;
}

/***************************************************/

memset(szRecvbuf,0,MAX_PACKET);
//dés la prmiere ping : si on a l'envoi est supérieur de perte on sort
if((CHote->iNbRetryUsed-iPerte)>0)
bRstConn=true;

}
}
while(iFindelai == 0);
}