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 :

les erreurs de pthread_create


Sujet :

POSIX C

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 74
    Points : 56
    Points
    56
    Par défaut les erreurs de pthread_create
    Bonjour tout le monde,

    J’ai écris une application qui crée plusieurs thread et à un moment donnée la fonction pthrerad_create commence à échouer et elle me retourne une valeur égale à 12.

    Pourriez-vous m'expliquer que signifie cette erreur.

    merci d'avance.

  2. #2
    Membre expérimenté Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Points : 1 544
    Points
    1 544
    Par défaut
    Bonjour,

    peut etre un bout de reponse ici, en regardant les differentes maccros de retour d erreurs EINVAL, EPERM....

    sinon peut etre qu en nous montrant un bout de code on pourra plus t aider...
    "vaste programme"

  3. #3
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Le fonction perror peut aussi donner une bonne idée de la cause de l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if(0 != pthread_create(...)) {
        perror("Impossible de créer un nouveau thread :");
    }

  4. #4
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 74
    Points : 56
    Points
    56
    Par défaut
    effectivement avec perror j'ai eu l'interpretation de l'erreur:

    cannot allocate memory
    sincerement je ne la comprends pas !!??

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut elles font quoi ces threads?
    La mémoire est une ressource partagée par les différents threads (crées).
    Il serait peut être bon de s'inquiéter de ce qu'elles allouent directement (via malloc ou pile) ou indirectement si elles utilisent des bibliothèques.
    - W
    PS: sur quel type d'environnement (Windows, Linux, autres) cela se passe?
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par sofiane80 Voir le message
    J’ai écris une application qui crée plusieurs thread et à un moment donnée la fonction pthrerad_create commence à échouer et elle me retourne une valeur égale à 12.

    Pourriez-vous m'expliquer que signifie cette erreur.
    Si ça signifie 'erreur d'allocation mémoire', c'est qu'il n'y a plus de mémoire disponible. Est-ce que tu libères bien tout ce qui a été alloué dans un thread ?
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 74
    Points : 56
    Points
    56
    Par défaut presque résolu
    en fait je développe un serveur qui crée un thread pour chaque connection, la plus part de mes thread on une courte durée de vie il s'achève dès que la connexion est fermée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    while((newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&clilen))>0){
       if ((thread_err=pthread_create (&getmetadata, NULL, getmetadata_process, (void *)download)) != 0){
          error ("Impossible de créer le thread connection\n",0);
    	close(newsockfd);
    	free(download->hashm);
    	ree(download);
     
        }
     
           else 
                printf("passif_process:une nouvelle connexion a été crée \n");
     
    }
    avec ce code, et bien que je libere tous ce qui est alloué au viveau de chaque thread, j'avais assez tôt l'erreur "cannot allocate memory" ( pas plus de 10 thread qui tourne simultanement)

    quelqu'un m'avait proposé je rajouter les lignes de codes suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
    et créer mes threads comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    pthread_create (&getmetadata, &attr, getmetadata_process, (void *)download)
    ceci m'a permet d'avancer un petit peu . Mais je me suis retrouvé avec le même problème après avoir 303 threads qui tourne au même temps.

    ps: je travaille sous linux

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Certes PTHREAD_DETACH permet de libérer la mémoire sans attendre un pthread_join... Cela conforte l'oubli de désallouer de la mémoire à chaque fois qu'une thread se termine.

    Note: les structures de données éventuellement crée autour de l'accept et du pthread_create n'ont pas une taille nulle ;-(

    Serait-il possible de connaitre le nombre total de threads crées (en comptant celles qui se sont déjà terminée) plutôt que le nombre de threads active simultanées: cela nous donnerait peut être une meilleure idée de la quantité de mémoire perdue / thread ?
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par sofiane80 Voir le message
    avec ce code, et bien que je libere tous ce qui est alloué au viveau de chaque thread, j'avais assez tôt l'erreur "cannot allocate memory" ( pas plus de 10 thread qui tourne simultanement)
    J'ai essayé de le rendre lisible :
    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
     
       while ((newsockfd =
               accept (sockfd, (struct sockaddr *) &cli_addr, &clilen)) > 0)
       {
          thread_err =
             pthread_create (&getmetadata, NULL, getmetadata_process,
                             (void *) download);
     
          if (thread_err != 0)
          {
             error ("Impossible de créer le thread connection\n", 0);
             close (newsockfd);
             free (download->hashm);
             free (download);
          }
          else
          {
             printf ("passif_process:une nouvelle connexion a été crée \n");
          }
       }
    ce code est faux ou incomplet. On ne sait pas d'où vient 'download'. En tout cas, il ne peut pas être modifié par la tâche. On voit qu'il pointe sur un bloc alloué (puisque libéré en cas d'erreurs), mais on ne sait pas comment ni par qui.

    De plus, l'information capitale 'newsockfd ' n'est pas transmise à la tache (attention, 'getmetadata_process' est mal nommée, c'est un thread ou tache ou task, mais certainement pas un proces[sus]).

    Peux tu montrer une version compilable et testable qui montre le défaut ?
    Pas de Wi-Fi à la maison : CPL

  10. #10
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 74
    Points : 56
    Points
    56
    Par défaut
    désolé j'ai fait une erreur lors que j'ai copie/collé le code. je voulais juste poster la partie qui me blaque. voici une nouvelle version:

    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
     
    while ((newsockfd =
               accept (sockfd, (struct sockaddr *) &cli_addr, &clilen)) > 0)
       {
          download=(download_t *)malloc(sizeof (download_t));
          download->sockfd=newsockfd;
          download->hashm=(char *)malloc(T_HASH+1);
          memcpy(download->hashm,(char *)(bcm+2),(T_HASH+1));
          thread_err =
             pthread_create (&getmetadata, NULL, getmetadata_process,
                             (void *) download);
     
          if (thread_err != 0)
          {
             error ("Impossible de créer le thread connection\n", 0);
             close (newsockfd);
             free (download->hashm);
             free (download);
          }
          else
          {
             printf ("passif_process:une nouvelle connexion a été crée \n");
          }
       }
    download est de type download_t
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    typedef struct DOWNLOAD{
    	int sockfd;
    	char * hashm;
    	} download_t;

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Montrer un malloc dans une boucle while sans expliquer que le thread fera le free à tous les coups me semble à priori "suspect".
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #12
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 74
    Points : 56
    Points
    56
    Par défaut
    Citation Envoyé par sofiane80 Voir le message
    avec ce code, et bien que je libere tous ce qui est alloué au viveau de chaque thread, j'avais assez tôt l'erreur "cannot allocate memory" ( pas plus de 10 thread qui tourne simultanement)

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par sofiane80 Voir le message
    désolé j'ai fait une erreur lors que j'ai copie/collé le code. je voulais juste poster la partie qui me blaque. voici une nouvelle version:
    Il manque encore plein de choses Si tu ne postes pas du code compilable, on ne va deviner ce que tu as fait de travers...

    J'en suis là, mais j'ai déjà fait des hypothèses...
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
     
    /* 01.c */
     
    #ifdef __cplusplus
    #error Be sure you are using a C compiler...
    #endif
     
    #if defined (WIN32) || defined (_WIN32)
     
    #include <winsock2.h>
     
    #elif defined (linux) || defined (_POSIX_VERSION) || defined (_POSIX2_C_VERSION)\
     || defined (_XOPEN_VERSION)
     
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>             /* close */
     
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
     
    #define closesocket(s) close (s)
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
     
    #else
    #error not defined for this platform
    #endif
     
    #include <stdio.h>
    #include <stdlib.h>
     
    #include <pthread.h>
     
    /* macros ============================================================== */
    #define T_HASH 128
    /* constants =========================================================== */
    /* types =============================================================== */
    /* structures ========================================================== */
    typedef struct
    {
       int sockfd;
       char *hashm;
    }
    download_t;
     
    /* private data ======================================================== */
    /* private functions =================================================== */
     
    static void error (char const *msg, int a)
    {
       printf ("ERR : %d : %s\n", a, msg);
    }
     
    static void *getmetadata_process (void)
    {
       return 0;
    }
     
    static int server (void)
    {
       SOCKET sockfd = 0;
       SOCKET newsockfd;
       SOCKADDR_IN cli_addr = { 0 };
       int clilen = sizeof cli_addr;
     
       char bcm[256] = "";
     
       while ((newsockfd =
               accept (sockfd, (struct sockaddr *) &cli_addr, &clilen)) > 0)
       {
          pthread_t getmetadata;
     
          download_t *download = (download_t *) malloc (sizeof (download_t));
          download->sockfd = newsockfd;
          download->hashm = (char *) malloc (T_HASH + 1);
          memcpy (download->hashm, (char *) (bcm + 2), (T_HASH + 1));
          {
             int thread_err =
                pthread_create (&getmetadata, NULL, getmetadata_process,
                                (void *) download);
     
             if (thread_err != 0)
             {
                error ("Impossible de créer le thread connection\n", 0);
                closesocket (newsockfd);
                free (download->hashm);
                free (download);
             }
             else
             {
                printf ("passif_process:une nouvelle connexion a été crée \n");
             }
          }
       }
     
       return 0;
    }
     
    /* entry point ========================================================= */
     
    /* ---------------------------------------------------------------------
       --------------------------------------------------------------------- */
    int main (void)
    {
       int ret;
     
    #if defined (WIN32) || defined (_WIN32)
       WSADATA wsa_data;
       int err = WSAStartup (MAKEWORD (2, 2), &wsa_data);
     
       if (!err)
       {
          puts ("WIN: winsock2: OK");
    #else
       int err;
    #endif
     
       server ();
     
    #if defined (WIN32) || defined (_WIN32)
       WSACleanup ();
    }
    #endif
     
    if (err)
    {
       ret = EXIT_FAILURE;
    }
    else
    {
       ret = EXIT_SUCCESS;
    }
     
    return ret;
    }
    Pas de Wi-Fi à la maison : CPL

Discussions similaires

  1. [Htaccess] Gérer les erreurs HTTP du type 404...
    Par Marshall_Mathers dans le forum Apache
    Réponses: 4
    Dernier message: 01/07/2004, 10h29
  2. question sur les erreurs de compilation
    Par vince3320 dans le forum C
    Réponses: 5
    Dernier message: 19/04/2004, 11h34
  3. Recuperer les erreurs des requetes sql en asp
    Par emile13 dans le forum ASP
    Réponses: 3
    Dernier message: 01/04/2004, 13h49
  4. [web] comment afficher les erreur d'un cgi
    Par chtiboss dans le forum Web
    Réponses: 6
    Dernier message: 24/12/2003, 11h22
  5. Empecher les erreurs du débogeurs
    Par remixtech dans le forum EDI
    Réponses: 9
    Dernier message: 04/06/2003, 13h45

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