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

POSIX C Discussion :

Problème de creation de thread sous linux


Sujet :

POSIX C

  1. #1
    Membre du Club
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Points : 49
    Points
    49
    Par défaut Problème de creation de thread sous linux
    Salut

    J'ai créé une application nécessitant de créer de nombreux threads mais bizarrement, au bout d'un certain nombre, je ne peux plus en créer.

    Je détaille :

    Je suis sous linux en noyau 2.4.x et glibc 2.2.x . J'ai créé une application multithread graphique (sous X) et j'utilise les fonctions pthread_ pour gerer mes threads.

    Voici mon pb (peut etre je m'y prends mal) :

    j'ai un thread de reception qui lit sur le port série des trames de facon asynchrone (sous entendu je ne peux pas prévoir quand je les recois) et qui dispatche le resultat dans l'application selon certains parametres.
    J'ai une tâche qui consiste a scanner un certain nombre d'appareil (en parametre dans un fichier) sur un bus CAN , et ce scan se fait via le meme port serie (en émission cette fois ci). On imagine par exemple que j'ai X appareil, j'envoie donc une série de X trames tous les y ms et j'attends la reponse.
    Seulement je ne peux pas attendre la reponse d'un appareil avant d'envoyer la trame suivante (puisque si un appareil ne repondait pas, le process se retrouverait bloqué), j'envoie donc toutes les trames d'un coup (espacée de y ms) et a chaque envoi, je cree un thread qui va "attendre" 2000 ms, et au bout de ces 2000ms si la trame n'a pas été recue, met un flag pour dire que l'appareil ne repond et se termine.

    Au final on a donc X threads créés , qui se terminent chacun au bout de 2000ms.

    Mais apparemment ca ne fonctionne pas, en effet l'algo fonctionne parfaitement, mais au bout d'un certain nombre de thread créés , je ne peux plus en créer (valeur de retour de pthread_create retourne une erreur). Je suis obligé de quitter l'application pour pouvoir a nouveau en créer.

    Je pense donc que j'ai fait une erreur quelque part mais je ne vois pas bien ou.


    Je donne un code exemple qui resume ce que j'ai fait :




    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
     
    // fonction qui lance l'ecriture des trames
     
    void StartScan() {
    int ret;
    MODULE *m = m_pListModule;
     
     
    while (m != NULL) {
          m_pBitbus->Sendrequest(m->dwID); // envoie la trame sur le port serie
          ret = pthread_create(m->hThreadDelay,NULL,DelayThreadFunc,m);
          if (ret != 0) {
               Log(LOGLEVEL_ERROR,"Error : creating thread");
          }
    }
    }
     
    //fonction de thread
     
    void *
    DelayThreadFunc(void * pParam) {
    MODULE *m = (MODULE *)pParam;
     
    usleep(m->timeToLeave);
     
    if (m->dwReceiveFlag != REQUEST_RECEIVED) {
          m->dwReceiveFlag = REQUEST_NOTRESPONDING;
    }
    return NULL;
    }
    Je n'ai pas tout mis le code mais l'idée est la.

    Pour moi, le thread se termine lorsque la fonction associée (ici DelayThreadFunc) se termine, mais ca n'a l'air visiblement pas le cas. Aurai-je oublié un détail important ?

    Merci de m'avoir lu jusqu'au bout

  2. #2
    Membre du Club
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Points : 49
    Points
    49
    Par défaut
    je poste un autre code beaucoup plus simple pour comprendre mon probleme (complet cette fois ci):

    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
     
    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
     
    void *ThreadFunc(void *pParam) {
        static int i = 0;
        printf("Thread n° %d\n",i++);
        return NULL;
    }
     
    int main() {
     int ret,j;
     pthread_t thread;
     
     
      for (j = 0; j < 1000; j++) {
             usleep(10000); // 10 ms
             int ret = pthread_create(&thread,NULL,ThreadFunc, NULL);
             if (ret != 0) {
                  printf("Erreur creation thread (%d)\n",ret);
             }
      }
     
    return 0;
    }

    Voila. Au bout d'environ 230 threads créés, je ne peux plus jamais en créer. Il faut que je quitte mon programme et que je le relance pour pouvoir a nouveau en créer.
    Je comprends tout a fait qu'il y ait une limite au nombre de thread simultanés (ulimit -n = 1024 sur ma machine) , mais je ne comprends pas pourquoi cette limite est egalement le nombre de thread créés qu'ils soient terminés ou non. C'est une sacrée limitation dans ce cas.

  3. #3
    Responsable technique

    Avatar de Anomaly
    Homme Profil pro
    Directeur
    Inscrit en
    Juin 2003
    Messages
    10 332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Directeur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 332
    Points : 130 178
    Points
    130 178
    Billets dans le blog
    1
    Par défaut
    C'est normal. Tes threads ne sont pas encore morts, bien qu'ils en ait l'air

    Le programme principal qui crée le thread doit, à un moment ou à un autre, attendre la fin d'exécution du thread qu'il a créé. Cela permet non seulement une synchronisation (s'assurer qu'un thread est bien terminé avant de commencer une autre tâche sur le même sujet) mais aussi de lire sa valeur de retour qui serait perdue sinon. Cette synchronisation se fait avec pthread_join(). Après l'appel de cette fonction, le thread est définitivement envoyé au paradis des threads et les ressources libérées.

    Si tu n'as pas avoir besoin ni de te synchroniser avec la fin du thread, ni de lire sa valeur de retour, alors une solution plus simple est de détacher le thread. Un thread en mode détaché s'auto-détruira totalement à la fin de la fonction. Dans ton cas, le détachement s'impose.

    Pour détacher un thread, le plus simple est d'appeler pthread_detach(pthread_self()); au début de ta fonction de thread.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void *ThreadFunc(void *pParam) {
        static int i = 0;
        pthread_detach(pthread_self());
        printf("Thread n° %d\n",i++);
        return NULL;
    }
    Responsable technique forum & site

    Si ce message (ou un autre) vous a aidé et/ou vous semble pertinent, votez pour lui avec

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    Il est aussi possible de les créer détachés :
    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
    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
     
    void *ThreadFunc(void *pParam) {
        static int i = 0;
        printf("Thread n° %d\n",i++);
        return NULL;
    }
     
    int main() {
     int ret,j;
     pthread_t thread;
     pthread_attr_t attribut;
     pthread_attr_init(&attribut);
     pthread_attr_setdetachstate(&attribut,PTHREAD_CREATE_DETACHED);
     
      for (j = 0; j < 1000; j++) {
             usleep(100); // 10 ms
             int ret = pthread_create(&thread,&attribut,ThreadFunc, NULL);
             if (ret != 0) {
                  printf("Erreur creation thread (%d)\n",ret);
             }
      }
     
    return 0;
    }

  5. #5
    Membre du Club
    Inscrit en
    Octobre 2004
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 59
    Points : 49
    Points
    49
    Par défaut
    ok merci c'est sympa ca fonctionne à présent.

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

Discussions similaires

  1. les threads sous linux
    Par yashiro dans le forum Linux
    Réponses: 2
    Dernier message: 13/01/2007, 09h22
  2. prb avec un thread sous linux
    Par kikoufr dans le forum POSIX
    Réponses: 5
    Dernier message: 02/09/2006, 19h55
  3. [Tomcat] Problème de fonctionnement de Tomcat sous linux
    Par lautux dans le forum Tomcat et TomEE
    Réponses: 5
    Dernier message: 18/03/2006, 10h30
  4. Réponses: 11
    Dernier message: 14/02/2006, 00h26

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