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

GTK+ avec C & C++ Discussion :

g_idle_add bloque la boucle principale


Sujet :

GTK+ avec C & C++

  1. #1
    Membre à l'essai
    Inscrit en
    Mai 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 20
    Points : 16
    Points
    16
    Par défaut g_idle_add bloque la boucle principale
    Bonjour,

    J'utilise une fonction appelé f_ecriture_cmd qui permet de lancer une commande avec l'aide d'un fork. Elle recupere ce que l'executable envoi sur le terminal grace a dup2. Lors de la lecture des valeurs envoyées, grâce à la fonction read, le programme ne répond plus pendant quelques secondes, la fenetre devient grisatre comme si il n'y avait plus de réponse puis reprend pour finir le code. Es ce normal que la fonction read bloque la boucle principal ou es ce une erreur dans mon 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
     
    gboolean f_ecriture_cmd(gpointer p_data)
    {
    	int p_to_cmd[2];
    	int p_from_cmd[2];
    	char bufferR[540];
     
    	/* Creation du pipe */
    	if(pipe(p_to_cmd)==-1)
    	{
    		f_error_prog("Pipe p_to_cmd(f_ecriture_cmd) err: ");
    		return FALSE;
    	}
    	if(pipe(p_from_cmd)==-1)
    	{
    		f_error_prog("Pipe p_from_cmd(f_ecriture_cmd) err: ");
    		return FALSE;
    	}
    	/* Creation du fork */
     
    	pid_fake = fork();
    	switch(pid_fake)
    	{
    		case (pid_t)-1:
    			f_error_prog("Fork -1(f_ecriture_cmd) err: ");
    		case (pid_t)0 :
    			f_cmd_execvp(p_to_cmd,p_from_cmd,p_cmd);
    	}
     
    	close(p_from_cmd[1]);
    	close(p_to_cmd[0]);
    	do
    	{
    		nr=read(p_from_cmd[0], bufferR, sizeof bufferR);
    		if(nr == -1)
    		{
    			f_error_prog("nr=-1 (f_ecriture_cmd) err: ");
    			break;
    		}
    		if(nr == 0)
    			break;
     
    		bufferR[nr]='\0';
    		p_return = gtk_label_get_label(GTK_LABEL(p_label_terminal_aireplay));
    		p_temp=malloc((strlen(bufferR)+strlen(p_return)+1)*sizeof(char));
    		if(p_temp == NULL)
    		{
    			f_error_prog("Allocation de p_temp impossible(f_ecriture_cmd) err: ");
    			return FALSE;
    		}
    		if(p_return != NULL)
    		{
    			if(strcpy(p_temp,p_return)==NULL)
    			{
    				f_error_prog("Copie de p_return dans p_temp impossible(f_ecriture_cmd) err: ");
    				return FALSE;
    			}
    		}
    		if(strcat(p_temp,bufferR)==NULL)
    		{
    			f_error_prog("Concatenation de bufferR dans p_temp impossible(f_ecriture_cmd) err: ");
    			return FALSE;
    		}
    		string = g_utf8(p_temp);
    		if(string != NULL)
    		{
    			gtk_label_set_label(GTK_LABEL(p_label_terminal_aireplay),string);
    			g_free(string);
    		}
    		if(p_temp !=NULL)
    			free(p_temp);
    	}
    	while(nr>0);
    	close(p_to_cmd[1]);
    	close(p_from_cmd[0]);
    	return FALSE;
    }
    Merci

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Points : 1 633
    Points
    1 633
    Par défaut
    Tant que du code de ta fonction f_ecriture_cmd s'exécute, la boucle principale est bloquée. Donc si elle met 3s à s'éxécuter, alors ton appli sera bloquée pendant ces 3s.

  3. #3
    Membre à l'essai
    Inscrit en
    Mai 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 20
    Points : 16
    Points
    16
    Par défaut
    Merci pour ta reponse.

    Je viens de me rendre compte que j'ai omis de dire que j'appel la fonction avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,f_ecriture_cmd, NULL, NULL);
    Normalement avec cette appel, le code s'execute en parallele avec le main. Je ne comprend pas pourquoi il bloque au moment de read.

  4. #4
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par zephyrin_damortien Voir le message
    Normalement avec cette appel, le code s'execute en parallele avec le main. Je ne comprend pas pourquoi il bloque au moment de read.
    Non, dans la description il est précisé que les sources associées à GMainContext sont exécutées dans un même thread et c'est le cas ici (cf les sources de la glib)

  5. #5
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Points : 1 633
    Points
    1 633
    Par défaut
    Non non, il s'exécute pas en parallèle, c'est synchrone, en gros la mainloop, ça ressemble à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while (TRUE) {
      gerer_signaux_widgets (...);
      gerer_timeout (...);
      gerer_idle_callbacks (...);
    }
    et gerer_idle_callbacks se contente d'appeler ta fonction sans rien faire de magique.

  6. #6
    Membre à l'essai
    Inscrit en
    Mai 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 20
    Points : 16
    Points
    16
    Par défaut
    Je vous remercie pour vos précisions.

    Je n'avais pas compris comme cela l'utilisation des g_idle.

    Je me suis tourné sur les gthreads, et cela marche comme je le voulais.

    Merci

  7. #7
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Points : 1 633
    Points
    1 633
    Par défaut
    Prends bien garde à ne pas appeler de fonction gtk+ depuis ton/tes thread (en dehors de g_idle_add qui te permet de faire invoquer une fonction par le thread principal, celui de la mainloop)

  8. #8
    Membre à l'essai
    Inscrit en
    Mai 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 20
    Points : 16
    Points
    16
    Par défaut
    Ok, merci pour ta précision.
    Je peux donc utiliser la fonction g_idle_add dans le gthread ou je dois le créer en dehors du gthread ?

    C'est juste à titre d'information.

    Merci encore

  9. #9
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Points : 1 633
    Points
    1 633
    Par défaut
    Oui tu peux l'appeler sans pb depuis ton gthread, par contre le callback sera appelé depuis le thread principal.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 02/04/2013, 12h49
  2. Boucle principale d'un programme
    Par Hoder dans le forum Débuter
    Réponses: 4
    Dernier message: 31/10/2010, 16h36
  3. purebasic runprogram( bloque la fenêtre principale
    Par chourmovs dans le forum PureBasic
    Réponses: 4
    Dernier message: 25/03/2010, 22h19
  4. Fenetre et boucle principale
    Par Katian dans le forum Développement 2D, 3D et Jeux
    Réponses: 2
    Dernier message: 19/12/2008, 16h28
  5. Réponses: 19
    Dernier message: 16/03/2008, 23h45

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