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 :

problème création thread


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2015
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2015
    Messages : 6
    Points : 1
    Points
    1
    Par défaut problème création thread
    Bonjour,

    j'ai un petit problème dans mon programme que je n'arrive pas a comprendre : le principe est que au début je créé un nouveau thread qui exécute une fonction bien précise et, dans le main, une interface attend un évènement de la souris. Si celui-ci est détecté, on arrête le thread courant et on le lance à nouveau sous le même nom avec un argument différent. Ce qui donne (succinctement) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    pthread_t MusicThread;
    pthread_create(&MusicThread, NULL, play_musique, &fichier);
     
    if (bouton_clic())
    {
       pthread_cancel(MusicThread);
       fichier.position_rep++;
       pthread_create(&MusicThread, NULL, play_musique, &fichier);
    }
    Mon problème étant que, pour une raison inconnue, quand l'évenement est détecté le thread ne se relance pas du tout. Tout est bien détecté et la variable est bien modifiée mais impossible de créer à nouveau le thread.

    Avez-vous une idée ?
    Merci d'avance.



    PS: j'utilise Code::Blocks et MinGW sous Windows.

  2. #2
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 851
    Points : 2 293
    Points
    2 293
    Par défaut
    Dans l'exemple donné dans le man, la fonction est appelée à l'intérieur du thread, mais comme elle prend un identifiant, je ne suis pas sûr que ce soit requis. Par-contre, il serait bien que tu attendes la fin de l'exécution de ton thread pour être sûr que tout est bon (avec pthread_join). Peux-tu ajouter ça et voir si ça résout ton problème ?

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2015
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2015
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Bonjour imperio,

    merci de ta réponse j'ai bien ajouté pthread_join, ce me semble en effet un peu plus clean. ceci dit le programme continue de planter
    Mais je peut être un peu plus précis: j'ai l'impression que c'est lors de l'annulation du thread qu'il y a un problème, il plante à peu près à cet endroit…

  4. #4
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 851
    Points : 2 293
    Points
    2 293
    Par défaut
    Je pense que c'est le code qui se situe dans ton thread qui pose problème. Pourrais-tu mettre tout ton code ?

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2015
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2015
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    C'est ce que je me suis dis pendant un moment mais je n'ai jamais pu trouver ce qui pouvait causer ce problème.
    Voici le code contenu dans le thread:

    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <fmod.h>
    #include <dirent.h>
    #include <pthread.h>
    #include <SDL2/SDL.h>
    #include "main.h"
     
    void play_musique(MUSIC_FILE *Fichier)
    {
     
        FMOD_SYSTEM *Systeme;
        FMOD_System_Create(&Systeme);
        FMOD_System_Init(Systeme, 1, FMOD_INIT_NORMAL, NULL);
        FMOD_BOOL Lecture = 1;
     
        unsigned int longeur;
     
        if (strstr(Fichier->chemin, ".mp3")!=NULL || strstr(Fichier->chemin, ".wav")!=NULL || strstr(Fichier->chemin, ".wmv")!=NULL)
        {
            FMOD_SOUND *Musique=NULL;
            if (FMOD_System_CreateStream(Systeme, Fichier->chemin, FMOD_2D | FMOD_LOOP_NORMAL, 0, &Musique)==-1) exit(EXIT_FAILURE);
            FMOD_Sound_GetLength(Musique, &longeur, FMOD_TIMEUNIT_MS);
            FMOD_Sound_SetLoopCount(Musique, Fichier->Loop_Status);
            FMOD_System_PlaySound(Systeme, Musique, 0, 0, &Fichier->cannal);
     
            SDL_Delay(longeur);
            while (Lecture!=0) FMOD_Channel_IsPlaying(Fichier->cannal, &Lecture);
        }
     
        else
     
        {
     
            DIR *repertoire=NULL;
            struct dirent *fichier_musique = NULL;
            repertoire = opendir(Fichier->chemin);
            if (repertoire==NULL) exit(EXIT_FAILURE);
            char nom_fichier[128];
            int i;
            if (Fichier->liste_fichiers == NULL)
            {
                if ((Fichier->liste_fichiers=malloc(2*sizeof(long))) == NULL) exit(EXIT_FAILURE);
                Fichier->liste_fichiers[0] = 3;
                for (i=0; i<2; i++) fichier_musique = readdir(repertoire);
                i = 1;
                while ((fichier_musique=readdir(repertoire)) != NULL)
                {
                    if (strstr(fichier_musique->d_name, ".mp3")!=NULL || strstr(fichier_musique->d_name, ".wav")!=NULL || strstr(fichier_musique->d_name, ".wmv")!=NULL)
                    {
                        Fichier->liste_fichiers[i] = telldir(repertoire);
                        if ((Fichier->liste_fichiers = realloc(Fichier->liste_fichiers, sizeof(long))) == NULL) exit(EXIT_FAILURE);
                        i++;
                    }
                }
                Fichier->liste_fichiers[i] = -1;
            }
            seekdir(repertoire, Fichier->liste_fichiers[Fichier->position_rep]-1);
            do
            {
                fichier_musique = readdir(repertoire);
                if (fichier_musique!=NULL)
                {
     
                    strcpy(nom_fichier, Fichier->chemin);
                    strcat(nom_fichier, fichier_musique->d_name);
     
                    if (strstr(nom_fichier, ".mp3")!=NULL || strstr(nom_fichier, ".wav")!=NULL || strstr(nom_fichier, ".wmv")!=NULL)
                    {
                        FMOD_SOUND *Musique=NULL;
                        if (FMOD_System_CreateStream(Systeme, nom_fichier, FMOD_2D | FMOD_LOOP_NORMAL, 0, &Musique) != -1)
                        {
                            FMOD_Sound_GetLength(Musique, &longeur, FMOD_TIMEUNIT_MS);
                            FMOD_Sound_SetLoopCount(Musique, Fichier->Loop_Status);
                            FMOD_System_PlaySound(Systeme, Musique, 0, 0, &Fichier->cannal);
     
                            SDL_Delay(longeur);
                            while (Lecture!=0) FMOD_Channel_IsPlaying(Fichier->cannal, &Lecture);
                        }
                        Fichier->position_rep++;
                        seekdir(repertoire, Fichier->liste_fichiers[Fichier->position_rep]-1);
                    }
                }
            }
            while (fichier_musique != NULL);
     
            free(Fichier->liste_fichiers);
            closedir(repertoire);
        }
        FMOD_System_Close(Systeme);
        FMOD_System_Release(Systeme);
        pthread_exit(0);
    }
    et voici le main.h

    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
     
    #ifndef MAIN_H_INCLUDED
    #define MAIN_H_INCLUDED
    #include <string.h>
    #include <fmod.h>
    #include <SDL2/SDL.h>
     
    typedef struct {
        SDL_Rect Coord;
        SDL_Texture* texture_mvmt;
        SDL_Texture* texture_clic;
    } BOUTON;
     
    typedef struct {
        char chemin[128];
        long position_rep;
        long *liste_fichiers;
        FMOD_CHANNEL *cannal;
        float Volume_Status;
        unsigned int Loop_Status;
        FMOD_BOOL Pause;
    } MUSIC_FILE;
     
    #endif // MAIN_H_INCLUDED

  6. #6
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 851
    Points : 2 293
    Points
    2 293
    Par défaut
    Arf, ça commence mal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FMOD_SYSTEM *Systeme;
    FMOD_System_Create(&Systeme);
    FMOD_System_Init(Systeme, 1, FMOD_INIT_NORMAL, NULL);
    Ça doit être fait une seule et unique fois.

    Je ne comprends pas vraiment l'intérêt de cette ligne :

    Un Sleep ça marche bien aussi...

    De manière générale, je ne comprends pas l'intérêt de ton thread. On utilise généralement un thread pour effectuer des tâches pour soulager le processus principal (ou parce que lui est occupé à faire autre chose). Je n'ai pas l'impression que ce soit ton cas.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2015
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2015
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par imperio Voir le message
    Arf, ça commence mal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FMOD_SYSTEM *Systeme;
    FMOD_System_Create(&Systeme);
    FMOD_System_Init(Systeme, 1, FMOD_INIT_NORMAL, NULL);
    Ça doit être fait une seule et unique fois.
    Ah oui en effet je n'avais pas pensé à ce détail…

    Citation Envoyé par imperio Voir le message
    Je ne comprends pas vraiment l'intérêt de cette ligne :

    Un Sleep ça marche bien aussi...
    voui c'est vrai, sur le coup j'étais en plein dans la SDL et c'est donc le premier truc auquel j'ai pensé…

    Citation Envoyé par imperio Voir le message
    De manière générale, je ne comprends pas l'intérêt de ton thread. On utilise généralement un thread pour effectuer des tâches pour soulager le processus principal (ou parce que lui est occupé à faire autre chose). Je n'ai pas l'impression que c'est ton cas.
    Bon alors en gros le principe est que je cherche à faire un lecteur de musique qui peut lire un dossier en entier. le probleme est l'interface graphique (avec la SDL): pour économiser le processus j'utilise SDL_WaitEvent, mais si je met le programme en pause il ne pourra pas passer a la musique suivante quand la précédente sela terminée. Donc je fais un thread qui ne fait que lire les fichiers dans le dossier et l'interface est dans le processus principal.

    Tu pense qu'il y a une façon plus simple de faire ça?

  8. #8
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 851
    Points : 2 293
    Points
    2 293
    Par défaut
    J'avais écrit un lecteur de musique en SDL en C (que je suis en train de réécrire en Rust pour le coup). Je n'avais pas de thread, on pouvait changer de musique en cliquant dessus, mettre en pause, etc... FMOD fournit des fonctions pour faire tout ça, absolument aucun besoin de thread, et j'insiste lourdement sur ce point. Donc en gros, tu update écran 60 fois par seconde (par super utile d'aller aussi vite mais qu'importe), et à chaque fois, tu vérifies si ta musique est finie. Si c'est le cas, tu passes à la suivante. Rien de bien sorcier.

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2015
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2015
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    C'est en effet ce que j'avais fait au début, le problème c'est précisément l'update de l'écran: il faut faire une boucle qui a donc la fâcheuse tendance à consommer pas mal d'UC. Honnêtement, pour avoir fait le test ça ne m'a pas convaincu du tout; d'autant plus que je cherche à faire un lecteur minimaliste qui n'utilise pas le processeur (ou presque). C'est tout à fait possible car quand FMOD lit un fichier il ne consomme rien du tout. Donc inutile de faire tourner un programme et toute une interface graphique alors qu'il ne fait que lire un fichier. D'où l'utilité du thread. Je n'ai rien trouvé dans FMOD qui puisse permettre de lire un dossier, mais il est tout à fait possible que j'ai manqué qqch, je ne connais pas la librairie par cœur…

  10. #10
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 851
    Points : 2 293
    Points
    2 293
    Par défaut
    Je pense que t'y es très mal pris. Mon lecteur a beaucoup d'affichage et ne commence pourtant pratiquement pas de CPU. Le fait de gérer fmod dans un thread n'y changera rien. Et non, je ne pense pas que fmod permette de lire tout un dossier, il faudra que tu le fasses toi-même (ce qui n'est pas très compliqué en soi cela dit).

  11. #11
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2015
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2015
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par imperio Voir le message
    Je pense que t'y es très mal pris. Mon lecteur a beaucoup d'affichage et ne commence pourtant pratiquement pas de CPU.
    Je n'en doute pas, à mon avis c'est aussi dût au fait que mon PC est une machine à laver. '--

    Citation Envoyé par imperio Voir le message
    Le fait de gérer fmod dans un thread n'y changera rien.
    Ben en l'occurence, si… en ce moment mon lecteur ne fonctionne qu'à moitié, il marche quand même si je lui demande de lire un fichier unique, et la différence par rapport à mon ancien code est flagrante. Pourtant j'avais fait une boucle toute simple, un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    FMOD_PlaySound();
    while (FMOD_Channel_IsPlaying() && event.type == 0)
           PollEvent(&event);
    Tu me diras si il y a quelque chose qui ne va pas; mais je vais être honnête, ce qui m'intéresse ici c'est manipuler les thread. C'est qqch que je ne connais pas assez à mon goût et l'idée de ce programme était précisément que j'apprenne à utiliser pthread. C'est pourquoi je cherche à résoudre ce problème sans utiliser autre chose qu'un thread. Mais merci quand même de ton aide, elle m'est fort utile

  12. #12
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    851
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 851
    Points : 2 293
    Points
    2 293
    Par défaut
    Je n'en doute pas, à mon avis c'est aussi dût au fait que mon PC est une machine à laver. '--
    Ça ne devrait pas vraiment poser de problème...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FMOD_PlaySound();
    while (FMOD_Channel_IsPlaying() && event.type == 0)
           PollEvent(&event);
    Tout le code de mon lecteur se trouvait dans une boucle similaire. J'utilisais aussi SDL_Delay pour éviter de trop faire tourner mon CPU (comme tu l'avais fait dans le thread).

    Tu me diras si il y a quelque chose qui ne va pas; mais je vais être honnête, ce qui m'intéresse ici c'est manipuler les thread. C'est qqch que je ne connais pas assez à mon goût et l'idée de ce programme était précisément que j'apprenne à utiliser pthread. C'est pourquoi je cherche à résoudre ce problème sans utiliser autre chose qu'un thread. Mais merci quand même de ton aide, elle m'est fort utile
    Hum... Dans ce cas je pense qu'il vaudrait mettre les traitements lourds dans un thread (genre la génération du spectre par exemple). FMOD n'est (normalement) pas la partie qui commence le plus. Tu pourras découvrir les mutex de cette façon. Si tu tiens vraiment à apprendre les threads, je trouve que le mieux reste encore une application avec une partie réseau. Essaie de te faire un chat avec une interface graphique, tu verras.

Discussions similaires

  1. création d'un serveur multi client (problème de thread)
    Par Benyou dans le forum Threads & Processus
    Réponses: 5
    Dernier message: 21/08/2013, 02h27
  2. Problème Création-Passage de paramètre Thread
    Par atum25 dans le forum Threads & Processus
    Réponses: 4
    Dernier message: 09/07/2012, 10h40
  3. Problèmes création de procédures et de triggers
    Par missllyss dans le forum SQL
    Réponses: 2
    Dernier message: 06/11/2003, 11h42
  4. Problème création de DLL
    Par monsieur.voie.lactee dans le forum C++Builder
    Réponses: 4
    Dernier message: 12/08/2003, 17h56
  5. [VC++6][DX9] Problème de thread lors d'un blit ...
    Par grandjouff dans le forum DirectX
    Réponses: 2
    Dernier message: 12/06/2003, 23h22

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