Comment rédémarer un thread automatiquement quand il se termine. [Résolu]

Signaler
Messages postés
52
Date d'inscription
jeudi 23 avril 2009
Statut
Membre
Dernière intervention
7 décembre 2011
-
Messages postés
41
Date d'inscription
lundi 10 septembre 2007
Statut
Membre
Dernière intervention
13 avril 2011
-
Bonjour,

Donc tous est dans le titre :

Méme si je pense que cela n'est pas trés propre je ne vois pas d'autre solution a mon probléme.

Voici mon thread si vous en avez besoin :

DWORD WINAPI EnvoieEmail ( LPVOID IpvThreadParam )
{
email();
Sleep(60000);

return 0;
}

   HANDLE hThreads [ 2 ] ;
   DWORD dwThreadId ;
   DWORD dwThreadParam = 1 ;
hThreads [ 1 ] = CreateThread ( NULL, NULL, EnvoieEmail, &dwThreadParam, 0, &dwThreadId ) ;
CloseHandle ( hThreads [ 1 ] ) ;



Voila en espérant que cela soit possible.

merci d'avance
jérémy

15 réponses

Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
Tu as toute une série de strcat(sender,exp) etc...
La première fois pas de problème... mais tu ne réinitialises pas ces variables (elles sont GLOBALES) donc à chaque fois que tu appelles la fonction t'ajoutes un truc derrière et forcément ça veut plus rien dire.
Voilà déjà un point à corriger, peut-être autre chose après.

Ensuite, bon, c'est pas super joli...
Tu utilises l'API (CreateThread etc...) donc autant le faire pour tout, notamment la lecture de fichier :
fonctions utiles CreateFile, GetFileSize, ReadFile...
Ca serait même plus élégant en l'occurence de passer par le file mapping :
CreateFileMapping et MapViewOfFile pour récupérer directement un pointeur sur le texte à transmettre, sans s'embêter à devoir le copier.
Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
DWORD WINAPI EnvoieEmail ( LPVOID IpvThreadParam )
{
lbl_Loop:
email();
Sleep(60000);
        goto lbl_Loop;
return 0;
}


ce qui ne répond pas vraiment à ta question mais a l'effet recherché;

ou bien :

DWORD WINAPI EnvoieEmail ( LPVOID IpvThreadParam )
{
email();
Sleep(60000);
return 0;
}


// fonction principale

lbl_Loop:
  HANDLE hThread=CreateThread(...);
  if(hThread)
  {
     WaitForSingleObject(hThread,INFINITE);
     CloseHandle(hThread);
  }
  goto lbl_Loop;
Messages postés
52
Date d'inscription
jeudi 23 avril 2009
Statut
Membre
Dernière intervention
7 décembre 2011

Merci beaucoup c exactement ce que je chercher , je penser que cela aller regler mon probléme mais enfaite non

en gros ma fonction email envoie le contenue d'un fichier .txt par email.
je souhaite qu'il y est un Sleep() pour pas non plus être flood d'email.

Mais il y a deux problèmes :

1- la fonction email ne se lance que 2 fois et je ne sais pas pourquoi ( en tous cas je ne reçoit que 2 email)
2- Le fichier .txt aura bien-sur changer entre le premier et les autre envoie mais on dirait qu'il garde en mémoire le 1er email car je reçoit toujours le même pour le second email alors que la fonction est normalement terminer la première fois et que j'initialise les variable

je vous colle ma fonction email.

En tous cas merci beaucoup pour goto (souvenir du basic ) cela va beaucoup me servir


jérémy
Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
Si tu as utilisé la première solution, faut pas que la fonction principale se termine avant les autres threads sinon ils sont tous arrêtés (le thread principal appelle ExitProcess()); d'où l'utilisation de WaitForSingleObject() et consorts, que tu peux mettre en fin de procédure éventuellement.
Bon, je ne sais pas si cela explique ton problème, faudrait mettre un peu plus de code.

Quant à goto, beaucoup de gens refusent de l'utiliser dans un code en C, soi-disant que ça engendre un manque de visibilité etc... Moi je crois que c'est juste à cause du Basic
En l'occurence il y avait d'autres possibilités pour une boucle infinie :
while(1)
{
   ...
}



for(;;)
{
   ...
}
Messages postés
52
Date d'inscription
jeudi 23 avril 2009
Statut
Membre
Dernière intervention
7 décembre 2011

Oups j'ai complètement oublier de coller ma fonction mail.
J'ai déjà essayer une boucle infinie avec while(1) mais cela ne marcher pas. J'ai l'impréssion que la seconde fois que la fonction email est lancer elle ne se termine pas je ne vois pas trop pourquoi cela fait sa.

#define TAILLE_MAX 10000

#include <winsock.h>
#include 
#include <string>
#include <stdlib.h>
#include <windows.h>
#include <stdio.h>
#include <cstdio>
#include <sstream>
#include <fstream>


#pragma comment(lib,"ws2_32.lib")
SOCKET to_server_socket = 0;
char * server_name;
int port = 25;

char destinataire[120] = "RCPT To: <";
char sender[120] = "MAIL From: <";
char * exp;
char * dest;
char * sujet;
char * message;
char buffer[15];
char body[1100] = "Subject: ";



void bcopy( void * source, void * destination, int size )
{
char * src = ( char * ) source;
char * dst = ( char * ) destination;

for( int i=0; i<size; i++ )
dst[i] = src[i];
}

void bzero( void * destination, int size )
{
char * dst = ( char * ) destination;

for( int i=0; i<size; i++ )
dst[i] = 0x00;
}

void Process( char * buffer )
{
Sleep( 1000 );

int size = strlen( buffer );
int retVal = send( to_server_socket, buffer, size, 0 );

char buf[ 1024 ];
buf[0] = 0x00;
while( !buf[0] )
int yeah = recv( to_server_socket, buf, 1024, 0 );

}

int email()
{
std::string contenue = "";
    FILE* fichier = NULL;
    char chaine[TAILLE_MAX] = "";
 
fichier = fopen("C:\\readme.txt", "r");
 
    if (fichier != NULL)
    {
        while (fgets(chaine, TAILLE_MAX, fichier) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL)
        {
            contenue += chaine;
        }
 
        fclose(fichier);
    }


//FILE* fichier2 = NULL;
//fichier2 = fopen("C:\\readme.txt", "w+" );
//fclose(fichier2);
const char *CstStr2 = contenue.c_str ();

if (contenue == "")
{
return 0;
}



if (strcmp(CstStr2,buffer) == 0) {
exit( -1 );
}
int not = 0;
unsigned long ioctl_blocking = 1;

/*cout<<"Entrez le nom du serveur smtp ou son ip\n";
cin>>server_name;
cout<<"Entrez l'adresse email de l'expediteur\n";
cin>>exp;
cout<<"\nEntrez l'adresse email du destinataire\n";
cin>>dest;
cout<<"\nEntrez le sujet du mail\n";
cin>>sujet;
cout<<"\nEntrez votre message\n";
cin>>message;*/

server_name = "smtp.orange.fr";
exp = "******";
dest = "*****";
sujet = "le sujet";

strcat(sender,exp);
strcat(sender,">\r\n");
strcat(destinataire,dest);
strcat(destinataire,">\r\n");
strcat(body,sujet);
strcat(body," \r\n\r\n ");
strcat(body,CstStr2);
strcat(body," \r\n.\r\n");

WSADATA wsaData;
if( int err = WSAStartup( 0x0101, &wsaData ) )
{

exit( -1 );
}


struct sockaddr_in serverSockAddr; // addresse de la socket
struct hostent * serverHostEnt; // description du host serveur
long hostAddr; // addr du serveur

bzero( &serverSockAddr, sizeof( serverSockAddr ) ); // initialise a zero serverSockAddr
// converti l'adresse ip 9.100.1.1 en entier long
hostAddr = inet_addr( server_name );

if( ( long ) hostAddr != ( long ) -1 )
bcopy( &hostAddr, &serverSockAddr.sin_addr, sizeof( hostAddr ) );
else // si on a donne un nom
{
serverHostEnt = gethostbyname( server_name );
if ( serverHostEnt == NULL )
{

exit( 0 );
}
bcopy( serverHostEnt->h_addr, &serverSockAddr.sin_addr, serverHostEnt->h_length );
}

serverSockAddr.sin_port = htons( port ); // host to network port
serverSockAddr.sin_family = AF_INET; // AF_*** : INET=internet
// creation de la socket

to_server_socket = socket( AF_INET, SOCK_STREAM, 0 );
if ( to_server_socket < 0)
{

exit( 0 );
}

setsockopt(to_server_socket, SOL_SOCKET, SO_DONTLINGER, (char *) &not, sizeof(not));


// requete de connexion
if( connect( to_server_socket, ( struct sockaddr * ) &serverSockAddr,
sizeof( serverSockAddr ) ) < 0 )
{

exit( 0 );
}

ioctlsocket ( to_server_socket, FIONBIO, &ioctl_blocking );

char buf[ 1024 ];
buf[0] = 0x00;
while( !buf[0] )
int yeah = recv( to_server_socket, buf, 1024, 0 );


Process( "EHLO Toto\r\n" );
Process( sender ); // mail de l'expediteur
Process( destinataire ); // mail du destinataire
Process( "DATA\r\n" );
Process( body );
Process( "QUIT\r\n" );
/* fermeture de la connection */
shutdown( to_server_socket, 2 );
contenue.erase();
closesocket( to_server_socket );
return 0;
}



jérémy
Messages postés
52
Date d'inscription
jeudi 23 avril 2009
Statut
Membre
Dernière intervention
7 décembre 2011

elle sont toute réinitialiser car on relit le fichier et on met le contenue dans CstStr2 donc vu que sa envoie comme contenue CstStr2 il ne devrait pas y avoir de problème.

toute les variable sont initialiser ou une valeur et défini avant l'envoie.
mais le fichier texte si il est modifier entre 2 envoie ne change pas il n'y a rien qui se rajoute.

je viens quand méme de modifier par :

char destinataire[120] = "RCPT To: <";
char sender[120] = "MAIL From: <";
char * exp = "";
char * dest = "";
char * sujet =  "" ;  
char * message  = "";
char buffer[15] = "";
char body[1100] = "Subject: ";


et cela na rien changer.

Cela est mon premier programme donc que cela ne soit pas jolie pour l'instant c pas trop grave je corrigerai sa quand il marchera car la j'en est besoin rapidement

jérémy
Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
Oui le problème c'est sur les variables sender, destinataire...
c'est celles-ci qui devraient être initialisées en début de fonction; regarde un peu leur contenu en cours d'exécution (tu peux les afficher dans la console par ex.)...
Messages postés
52
Date d'inscription
jeudi 23 avril 2009
Statut
Membre
Dernière intervention
7 décembre 2011

Tu avait raison cela venait bien de sa. merci beaucoup

jérémy
Messages postés
41
Date d'inscription
lundi 10 septembre 2007
Statut
Membre
Dernière intervention
13 avril 2011

bonjour,
si vous pouvez m'aider, je veux developper un thread qui lit à partir d'un fichier txt ligne par ligne avant d'inserer la ligne dans une BDD, pour le moment ce que je cherche c'est de créer un thread de lecture de fichier txt en C++ sous windows.
Merci d'avance

Tarik
Messages postés
52
Date d'inscription
jeudi 23 avril 2009
Statut
Membre
Dernière intervention
7 décembre 2011

Magicientarik je viens de te le faire en espérant que cela puisse t'aider, par contre je n'est pas eut le temps de tester.

DWORD WINAPI fonction ( LPVOID IpvThreadParam )
{

FILE* fichier = NULL;
char chaine[TAILLE_MAX] = "";

fichier = fopen("test.txt", "r");

if (fichier != NULL)
{
while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
{
printf("%s", chaine);
}

fclose(fichier);
}
return 0;

}

int main(int argc, char *argv[])
{
// initialisation des options pour la fonction CreateThread
HANDLE hThreads [ 2 ] ;
DWORD dwThreadId ;
DWORD dwThreadParam = 1 ;


// on crée le thread qui va démarrer le hook
hThreads = CreateThread ( NULL, NULL, fonction, &dwThreadParam, 0, &dwThreadId ) ;

WaitForSingleObject(hThreads,INFINITE);

CloseHandle ( hThreads ) ;

return 0;

}

jérémy
Messages postés
52
Date d'inscription
jeudi 23 avril 2009
Statut
Membre
Dernière intervention
7 décembre 2011

Tu dois faire aussi en début de code:

#define TAILLE_MAX 1000

avec la taille MAX de caractére par ligne.

actuelement cela affiche juste aprés a toi a voir pour l'ajout en abse de donnée car la je ne peut t'aider
Messages postés
41
Date d'inscription
lundi 10 septembre 2007
Statut
Membre
Dernière intervention
13 avril 2011

D'abord merci jerem pour ton aide,
en fait lorsque je compile ton programme, j'ai l'arreur suivante:
error C2440: '=' : cannot convert from 'void *' to 'void *[2]'
et le compilateur point sur :
[b]// on crée le thread qui va démarrer le hook
hThreads = CreateThread ( NULL, NULL, fonction, &dwThreadParam, 0, &dwThreadId ) ; /b
je suis débutant en C++ et surtout j'ai jamais travaillé avec les thread.
si vous pouvez m'aider à résouudre le problème
d'avance merci infiniment
Messages postés
41
Date d'inscription
lundi 10 septembre 2007
Statut
Membre
Dernière intervention
13 avril 2011

pour bien t'expliquer ce que je cherche,
on effet je veux developper une application multi threads, dont deux thread lisent de deux fichiers, et un autre equirit dans un troisième fichier, et pour ça j'ai pensé à définir une classe générique pour définir le thread, et les autre thread hérite du thread générique.
merci infiniment jerem
Messages postés
52
Date d'inscription
jeudi 23 avril 2009
Statut
Membre
Dernière intervention
7 décembre 2011

Je suis désoler j'ai fait un simple copier coller de mes thread mais comme il y en as plusieurs ce n'est pas pareil et j'ai oublier de corriger certaine choses.

Donc je viens te le refaire avec un seul thread donc ce n'est pas ce qui te faut mais je te le mets quand même.

#define TAILLE_MAX 1000

#include <cstdlib>
#include 
#include <windows.h>

using namespace std;

DWORD WINAPI fonction ( LPVOID IpvThreadParam ) 
{ 

FILE* fichier = NULL; 
char chaine[TAILLE_MAX] = ""; 

fichier = fopen("C:\\readme.txt", "r"); 

if (fichier != NULL) 
{ 
while (fgets(chaine, TAILLE_MAX, fichier) != NULL) 
{ 
printf("%s", chaine); 
} 

fclose(fichier); 
} 
return 0; 

} 

int main(int argc, char *argv[]) 
{ 
// initialisation des options pour la fonction CreateThread 
HANDLE hThreads  ; 
DWORD dwThreadId ; 
DWORD dwThreadParam = 1 ; 


// on crée le thread qui va démarrer le hook 
hThreads = CreateThread ( NULL, NULL, fonction, &dwThreadParam, 0, &dwThreadId ) ; 

WaitForSingleObject(hThreads,INFINITE); 

CloseHandle ( hThreads ) ; 

system("PAUSE");
return 0; 

}


et pour plusieurs threads

#define TAILLE_MAX 1000

#include <cstdlib>
#include 
#include <windows.h>

using namespace std;

DWORD WINAPI fonction ( LPVOID IpvThreadParam ) 
{ 

FILE* fichier = NULL; 
char chaine[TAILLE_MAX] = ""; 

fichier = fopen("C:\\readme.txt", "r"); 

if (fichier != NULL) 
{ 
while (fgets(chaine, TAILLE_MAX, fichier) != NULL) 
{ 
printf("%s", chaine); 
} 

fclose(fichier); 
} 
return 0; 

}

DWORD WINAPI fonction2 ( LPVOID IpvThreadParam )
{

return 0;
} 

int main(int argc, char *argv[]) 
{ 
// initialisation des options pour la fonction CreateThread 
HANDLE hThreads [ 2 ] ; 
DWORD dwThreadId ; 
DWORD dwThreadParam = 1 ; 


    hThreads [ 0 ] = CreateThread ( NULL, NULL, fonction, &dwThreadParam, 0, &dwThreadId ) ;
    hThreads [ 1 ] = CreateThread ( NULL, NULL, fonction2, &dwThreadParam, 0, &dwThreadId ) ;

    WaitForMultipleObjects ( 2, hThreads, TRUE, INFINITE) ;

    CloseHandle ( hThreads [ 0 ] ) ;
    CloseHandle ( hThreads [ 1 ] ) ;

system("PAUSE");
return 0; 

}


Voila je pense que avec celui multi thread tu as du comprendre ce qu'il te faut modifier pour ajouter des threads.


donc a augmenter a la taille qu'il te faut :

HANDLE hThreads [ 2 ] ;


Donc tous la pas besoin d'explication.
hThreads [ 3 ] = CreateThread ( NULL, NULL, NOM_DE_TA_FONCTION, &dwThreadParam, 0, &dwThreadId ) ;


Mettre dans WaitForMultipleObjects le nombre de thread que tu as ( dans l'exemple 2 )

et faire un CloseHandle.

Je ne pense pas avoir était très clair dans mes explication ( je ne suis pas très douer pour sa ), analyse le code tu verra ce n'est pas bien compliquer.

PS: désoler pour l'orthographe

jérémy
Messages postés
41
Date d'inscription
lundi 10 septembre 2007
Statut
Membre
Dernière intervention
13 avril 2011

Merci beaucoup jérémy, tu m'as trop aidé, ton code marche bien et j'ai pus arrivé à mon besoin,
son utilisé une classe générique je peux faire appel à plusieur thread.
Encore merci
dahni_tarik2005@hotmail.com