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

 C Discussion :

Threads => help !


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 67
    Par défaut Threads => help !
    Hello,

    Je voudrais optimiser mon programme. Dans ce programme j'ai une fonction dont voici le prototype : char genere(int nombre);

    Cette fonction fait appele elle même à d'autre fonction assez lente, du coup, je me suis renseigné et j'ai vu que je pouvais utiliser les threads (sous windows). Si j'ai bien compris, ce sont des petits process qui utilisent la même mémoire que le process père, autrement dit, au lieu d'appeler une fois la fonction, je peux l'appeler plusieurs fois via les thread, et donc augmenter la vitesse d'execution de mon programme.

    Bref, dans le cas présent, j'utilise une fonction qui génénère des nombres, donc si j'ai bien compris, j'appele une fois ma fonction normalemen, et ensuite je la rappele via les threads, pour la lancer en parallèle.

    Ma question est simple : comment faire ?

    J'ai lu un tuto sur sur les thread, j'ai pigé la théorie, mais je suis allé voire des exemples sur d'autres sites, je n'ai rien trouvé qui aille dans le sens du tuto (tout était différent), à ne rien y comprendre.

    Donc voilà, j'aimerais qu'on me montre comment utiliser les threads, de façon simple, claire et avec des exemples.

    Merci !

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Au niveau système, sous Windows, deux solutions:
    • Utiliser les fonctions _beginthreadex() (pour lancer le thread), WaitForSingleObject() (pour attendre qu'il se termine) et CloseHandle() (pour libérer les ressources)
    • Télécharger la bibliothèque pthread-win32 qui permet d'utililiser les fonctions de multithread POSIX


    Au niveau du multithreading lui-même, il faut déjà que ton algorithme soit parallélisable. Le principe, c'est que les traitements ne doivent pas être exactement les mêmes sur les deux threads, ce qui serait inutile.
    Par exemple, si tu veux répartir sur plusieurs threads une fonction qui fait la somme des entiers d'un tableau, il faut que chaque thread traite une partie différente du tableau. Et ensuite, chacun retourne sa somme partielle, et le thread principal fait l'addition.


    Exemple pour la somme sur deux threads:
    • Algorithme: somme entrelacée (chaque thread compte de deux en deux).
    • Remplir une structure de paramètres pour le second thread : Adresse du tableau, taille du tableau, index de départ (ici, 1) + une place pour retourner la somme partielle.
    • Créer le nouveau thread avec cette structure.
    • Faire la même chose dans le thread principal, mais en partant de 0 au lieu de 1
    • Une fois la boucle finie, attendre que l'autre thread se termine.
    • Additionner les sommes partielles.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 67
    Par défaut
    Merci pour cette réponse, donc si j'ai bien compris, 2 threads ne doivent pas faire la même chose, soit le bout de code suivant (j'aime bien les exemples concrets ;p) :

    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
    40
    41
    42
    43
    44
    45
    46
    47
    #include <stdlib.h>
    #include <stdio.h>
    #include <conio.h>
    #include <time.h>
     
    #define NOMBRE 200
     
    char genereip(int nombreip);
     
    int main(int argc, char* argv[])
    {
    genereip(NOMBRE);
    system("PAUSE");    
    return 0;
    }
     
    char genereip(int nombreip)
    {
         int i; 
         for (i = 0 ; i < nombreip ; i++)
               {
               int max = 254;
               int min = 1;
               srand (time(NULL));
               int nb;
               nb=min+(int) (rand() % (max+1-min));
               char ip[12];
               sprintf(ip,"192.168.1.%d",nb4);
               char out[] = " > null";
               char commande [512];
     
               strcpy(commande, "ping -n 1 "); 
               strcat(commande, ip);
               strcat(commande, out);
     
               int ret = system (commande);
               if (ret==0)
                          { 
                          printf("ip : %s => online !\n", ip);
                          }
                          else
                          { 
                          printf("ip : %s => offline \n", ip);
                          }
     
               }
    }
    Mon code m'affiche une liste de 200 adresse ip aléatoirement sur un réseau locale. C'est très lent, j'utilise system("ping"), j'aimerais bien trouver une façn plus rapide de tester si l'ip répond ou non.. faute de mieux dans l'immédiat, je me tourne donc vers les thread.

    Donc si je suis le raisonnement plus haut, il faudrait par exemple que divise NOMBRE, par le nombre de thread que je veux pour qu'ensuite chacun génèrent et testent un nombre X d'ip.

    Pouvez-vous me montrer comme ça se présenterait sur ce code ? Un visuel m'aiderait énormément pour comprendre le fonctionnement de tout ça.

    Par ailleurs, j'ai entendu plusieurs choses concernant les threads, visiblement il y en a plusieurs sortent, il en ressort qu'il vaut mieux passer par les pthread, peut être plus chaud à comprendre, mais le code ne change pas de linux à windows. Pourriez vous m'en dire plus ?

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Tu suis le raisonnement comme il faut, mais je n'ai pas vraiment le temps aujourd'hui de te montrer comment faire...

    Par contre: Tu ne dois pas appeler srand() dans la boucle. Il ne faut l'appeler qu'une seule fois (à vue de nez, je dirais une fois par thread)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 67
    Par défaut
    Bon, j'ai troucé ceci :

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #include <stdio.h>
     
    #include <pthread.h>
     
    static void *task_a (void *p_data)
    {
       int i;
     
       for (i = 0; i < 5; i++)
       {
          printf ("Hello world A (%d)\n", i);
       }
     
       (void) p_data;
       return NULL;
    }
     
    static void *task_b (void *p_data)
    {
       int i;
     
       for (i = 0; i < 7; i++)
       {
          printf ("Hello world B    (%d)\n", i);
       }
       (void) p_data;
       return NULL;
    }
     
    int main (void)
    {
       pthread_t ta;
       pthread_t tb;
     
       puts ("main init");
     
       pthread_create (&ta, NULL, task_a, NULL);
       pthread_create (&tb, NULL, task_b, NULL);
     
    #if 1
       pthread_join (ta, NULL);
       pthread_join (tb, NULL);
    #endif
     
       puts ("main end");
     
       return 0;
    }
    Puis-je partir sur cette base pour réaliser mon code ? Est-ce que cette utilisation des threads est adaptée à ce que je veux faire ?

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Ce code utilise pthread, donc si tu es sous Windows tu vas devoir télécharger la bibliothèque pthread-win32.

    Ensuite, le code est pas mal, simplement il y a des chances que tu n'aies pas besoin de task_b.

    Et entre le pthread_create() et le pthread_join(), on mettra une moitié des calculs (l'autre étant dans task_a), comme dans mon exemple.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 67
    Par défaut
    Bon, j'ai essayé avec le code du dessus, en collant ma fonction dans un thread, mais ça n'a rien changé, je veux dire ça compilait, ça se lançait tout bien, mais aucun gain..


    Je dois faire une erreur, merci de m'expliquer avec mon code comment bien réaliser la chose.

    voici le code :

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <conio.h>
    #include <time.h>
    #include <winsock2.h>
    #pragma comment(lib, "ws2_32.lib")
     
    #define NOMBRE 100
     
    char genereip(int nombreip);
     
    static void *task_a (void *p_data)
    {
         int i; 
         for (i = 0 ; i < NOMBRE ; i++)
               {
               int max = 254;
               int min = 1;
               srand (time(NULL));
               int nb;
               nb=min+(int) (rand() % (max+1-min));
               char ip[12];
               sprintf(ip,"192.168.1.%d",nb);
               char out[] = " > null";
               char commande [512];
     
               strcpy(commande, "ping -n 1 "); 
               strcat(commande, ip);
               strcat(commande, out);
     
               int ret = system (commande);
               if (ret==0)
               {
               printf("ip : %s => online !\n", ip);      
               }
               }                     
       (void) p_data;
       return NULL;
    }
     
    int main(int argc, char* argv[])
    {
     genereip(NOMBRE);
       pthread_t ta;
     
       pthread_create (&ta, NULL, task_a, NULL);
    #if 1
       pthread_join (ta, NULL);
    #endif
     
    system("PAUSE");    
    return 0;
    }
     
    char genereip(int nombreip)
    {
         int i; 
         for (i = 0 ; i < NOMBRE ; i++)
               {
               int max = 254;
               int min = 1;
               srand (time(NULL));
               int nb;
               nb=min+(int) (rand() % (max+1-min));
               char ip[12];
               sprintf(ip,"192.168.1.%d",nb);
               char out[] = " > null";
               char commande [512];
     
               strcpy(commande, "ping -n 1 "); 
               strcat(commande, ip);
               strcat(commande, out);
     
               int ret = system (commande);
               if (ret==0)
               {
               printf("ip : %s => online !\n", ip);      
               }
    }

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    C'est parce que:
    • Ton nouveau thread doit appeler genereip(), pas la peine de dupliquer le code.
    • Ta fonction main() doit appeler genereip() entre le pthread_create() et le pthread_join() (tu peux retirer les #if 1 ... #endif, au passage)
    • Pour générer NOMBRE adresse, les deux appels à genereip() doivent être faits en leur passant NOMBRE/2 en paramètre (à supposer que NOMBRE soit pair, sinon c'est un poil plus compliqué).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Attention, rand n'est pas thread safe. Il est nécessaire d'utiliser la version réentrante : rand_r

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Dans ce cas, il faut séparer la compilation pour Windows et POSIX : Il n'y a pas de rand_r() sous Windows, mais la version Windows de rand() est thread-safe.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 67
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    C'est parce que:[*]Pour générer NOMBRE adresse, les deux appels à genereip() doivent être faits en leur passant NOMBRE/2 en paramètre (à supposer que NOMBRE soit pair, sinon c'est un poil plus compliqué).
    Mhh, je comprends pas bien.

    En fait, le thread doit appeler une moitié de nombre, et la fonction dans le main doit appeler l'autre c'est bien ça ?

    Donc dans le thread je dois appeler les 50 premier, et dans la fonction les 50 suivants ?

    edit : Je bloque, je vois pas comment, en partant de NOMBRE, générer dans un cas 50 premiers nombre, et dans le cas suivant 50 autres.. Je m'embrouille

    Sinon, je dois utiliser srand pour randomiser à chaque nouveau lancement (sinon les chiffres sont les même à chaque relancement du programme). Mais si vraiment srand empêche complètement le bon fonctionnement de mon programme, je m'en passerai.

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Essaie un truc de ce style (je préviens, je n'ai même pas essayé de compiler)
    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <conio.h>
    #include <time.h>
    #include <winsock2.h>
    #pragma comment(lib, "ws2_32.lib")
     
    #define NOMBRE 100
     
    void genereip(int nombreip);
     
    static void *task_a (void *p_data)
    {
    	(void) p_data;
    	srand(time(NULL));
     
    	genereip(NOMBRE/2);
     
    	return NULL;
    }
     
    int main(int argc, char* argv[])
    {
    	pthread_t ta;
     
    	pthread_create (&ta, NULL, task_a, NULL);
     
    	srand(time(NULL));
    	genereip(NOMBRE/2);
     
    	pthread_join (ta, NULL);
     
    	system("PAUSE");    
    	return 0;
    }
     
    void genereip(int nombreip)
    {
    	int i; 
    	for (i = 0 ; i < NOMBRE ; i++)
    	{
    		int max = 254;
    		int min = 1;
    		int nb;
    		char ip[16];
    		char out[] = " > null";
    		char commande [512];
     
    		nb=min+(int) (rand() % (max+1-min));
    		sprintf(ip,"192.168.1.%d",nb);
    		strcpy(commande, "ping -n 1 "); 
    		strcat(commande, ip);
    		strcat(commande, out);
     
    		int ret = system (commande);
    		if (ret==0)
    		{
    			printf("ip : %s => online !\n", ip);      
    		}
    	}
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 67
    Par défaut
    nope, marche pas : ça compile mais un message d'erreur au lancement du programme.

    En fait ça boucle gentiement, mais j'ai le message : "the process cannot acces the file bexause it is being user by another process".
    Et ça me fait ça juste après l'apparition de mon printf(" blablabla.. offline").

    edit : en fait, c'est curieux ça fait ça au début, mais vers le milieu le programme s'execute normalement.

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    C'est parce ce le fichier "trou" est "NUL" sous Windows, pas "null".

    De plus, ce n'est pas "null" non plus sous nux, c'est "/def/null".
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 67
    Par défaut
    Excuse moi, je saisis pas.. tu veux que je remplace mes "NULL" par "null" ? Si oui, j'ai essayé, là ça ne compile même plus.

  16. #16
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Non, que tu remplace char out[] = " > null"; par char out[] = " > NUL";

    Ou mieux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef WIN32
    char out[] = " > NUL"; /*Windows*/
    #else
    char out[] = " > /dev/null"; /*Autre*/
    #endif
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 67
    Par défaut
    Ok, oui, ce "null" là. Au temps pour moi.

    Ce petit détail corrigé, je reste bloqué pour le problème de base. Je compile bien, ça s'execute, mais il y a ce message d'erreur, malgré que les pings se fassent quand même.

    Voici où j'en suis :

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <conio.h>
    #include <time.h>
    #include <winsock2.h>
    #pragma comment(lib, "ws2_32.lib")
     
    #define NOMBRE 100
     
    char genereip(int nombreip);
     
    static void *task_a (void *p_data)
    {  
     	genereip(NOMBRE/2);             
       (void) p_data;
       return NULL;
    }
     
    int main(int argc, char* argv[])
    {
       pthread_t ta;
     
       pthread_create (&ta, NULL, task_a, NULL);
       genereip(NOMBRE);
    #if 1
       pthread_join (ta, NULL);
    #endif
     
    system("PAUSE");    
    return 0;
    }
     
    char genereip(int nombreip)
    {
         int i; 
         for (i = 0 ; i < NOMBRE ; i++)
               {
               int max2 = 200;
               int min2 = 100;
               srand (time(NULL));
               int nb;
               nb=min2+(int) (rand() % (max2+1-min2));
               char ip[12];
               sprintf(ip,"192.168.1.%d",nb);
               char out[] = " > NULL";
               char commande [512];
     
               strcpy(commande, "ping -n 1 "); 
               strcat(commande, ip);
               strcat(commande, out);
     
               int ret = system (commande);
               if (ret==0)
                          {
                          printf("ip : %s => online !\n", ip);
                          }
                          else
                          { 
                          printf("ip : %s => offline \n", ip);
                          }
     
               }
    }
    Pendant la première partie de l'execution du programme, j'ai ce message d'erreur qui apparait constamment : the process cannot acces the file bexause it is being user by another process. Juste après l'apparition de l'état de mon ip.

  18. #18
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    NULL
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  19. #19
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 67
    Par défaut
    ouiii, je suis bête, j'avais pas vu ! Merci

    bon, maintenant ça marche, enfin, je vois bien que le thread fonctionne, dans le sens où les résultat sortent bien par paquet "de deux".

    Le soucis que j'ai maintenant, c'est qu'il me sort deux fois la même ip, au lieu de tester deux ip différentes.

    edit : en fait, le thread est bien organisé je pense, c'est cette histoire de fonction qui génère les ip qui pose problème.. En gros, je lui demande deux fois de tester les même ip, il faudrait qu'à l'appele du second thread, je srand une autre ip.. Mais comment ?

    edit2: j'ai trouvé !! J'ai viré mon srand de ma fonction et je l'ai placé dans le main, juste avant l'appele de genereip() dans le thread.

    Merci à vous !

  20. #20
    Membre confirmé
    Inscrit en
    Février 2008
    Messages
    67
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 67
    Par défaut
    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <conio.h>
    #include <time.h>
    #include <winsock2.h>
    #pragma comment(lib, "ws2_32.lib")
     
    #define NOMBRE 100
     
    char genereip(int nombreip);
     
    static void *task_a (void *p_data)
    {  
     	genereip(NOMBRE/2);             
       (void) p_data;
       return NULL;
    }
     
    int main(int argc, char* argv[])
    {
       pthread_t ta;
     
       pthread_create (&ta, NULL, task_a, NULL);
      srand (time(NULL));
       genereip(NOMBRE);
    #if 1
       pthread_join (ta, NULL);
    #endif
     
    system("PAUSE");    
    return 0;
    }
     
    char genereip(int nombreip)
    {
         int i; 
         for (i = 0 ; i < NOMBRE ; i++)
               {
               int max2 = 200;
               int min2 = 100;
               int nb;
               nb=min2+(int) (rand() % (max2+1-min2));
               char ip[12];
               sprintf(ip,"192.168.1.%d",nb);
               char out[] = " > NULL";
               char commande [512];
     
               strcpy(commande, "ping -n 1 "); 
               strcat(commande, ip);
               strcat(commande, out);
     
               int ret = system (commande);
               if (ret==0)
                          {
                          printf("ip : %s => online !\n", ip);
                          /* Si je place ici du code qui travaille avec les sockets pour effectuer un test x ou y, je n'en vois le résultat que longtemps après exemple : */
                          int port = 80;
                          WSADATA WSAData;
                          WSAStartup(MAKEWORD(2,0), &WSAData);
                          SOCKET sock;
                          SOCKADDR_IN sin;
                          sock = socket(AF_INET, SOCK_STREAM, 0);
                          sin.sin_addr.s_addr = inet_addr(ip);
                          sin.sin_family     = AF_INET;
                          sin.sin_port     = htons(port); 
                          if((connect(sock,(struct sockaddr*)&sin,sizeof(struct sockaddr))) == 0)
                                 {
                                 printf("Port %.d ouvert\n",port);
                                 }                             
                                 else
                                 {
                                 printf("Port %.d ferme\n",port);
                                 }
                          }
                          else
                          { 
                          printf("ip : %s => offline \n", ip);
                          }
     
               }
    }
    bon, j'ai un autre petit pépin d'affichage, je pense qu'il ne s'agit que d'un problème d'affiche parceque mon code est peut être mal organisé.. quand je fais les tests si l'ip répond, je renvois un message, et en plus j'ouvre une nouvelle boucle me disant (par exemple) si le port de l'hote est ouvert ou non. Je pense que le résultat est correcte, le problème, c'est que le résultat envoyé n'apparait que plusieurs adresses ip plus tard, exemple :

    ip 192.168.1.1 => offline
    ip 192.168.1.2 => online !
    ip 192.168.1.3 => offline
    ip 192.168.1.4 => offline
    ip 192.168.1.5 => offline
    ip 192.168.1.6 => offline
    port 80 de 192.168.1.2 => ouvert
    ip 192.168.1.7 => offline
    ...
    alors que ça devrait me renvoyer ça :

    ip 192.168.1.1 => offline
    ip 192.168.1.2 => online !
    port 80 de 192.168.1.2 => ouvert
    ip 192.168.1.3 => offline
    ip 192.168.1.4 => offline
    ip 192.168.1.5 => offline
    ip 192.168.1.6 => offline
    ip 192.168.1.7 => offline
    ...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. Réponses: 1
    Dernier message: 24/02/2007, 14h02
  3. Programmer des threads
    Par haypo dans le forum C
    Réponses: 6
    Dernier message: 02/07/2002, 13h53
  4. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  5. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

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