Forum Programmation.c GTK : Forker depuis la boucle principale

Posté par  .
Étiquettes : aucune
0
16
déc.
2005
Bonsoir,

Voila, je réalise en ce moment une application en langage C qui s'appuie (notamment) sur GTK. Cependant, l'usage de l'interface graphique n'est pas systématique.

D'autre part, et c'est l'objet de mon post, je voudrais que cette application puisse forker et dæmoniser sur demande de l'utilisateur, c'est-à-dire sur un clic de l'utilisateur.

J'aimerais donc savoir s'il est possible de forker sans danger depuis une fonction de call back (pas faisable à mon avis) où s'il faut forcément sortir de la boucle principale auparavant, et si c'est le cas, est-ce que cela implique la destruction et la reconstruction de toutes les fenêtres et leurs widgets déclarés par le processus client ?

Merci à tous.
  • # pas clair ...

    Posté par  (site web personnel) . Évalué à 3.

    bien que n'ayant pas clairement compris ce que tu souhaitais faire, je vais tenter de fournir qq elements de reponses .

    Ce que je comprends de ce que tu souhaites faire :
    tu souhaites pouvoir avoir un demon qui puisse avoir une GUI ( reformulation de un processus qui peut devenir demon a la demande ).

    si tu forkes, tu cours vers un certains merdier si le pere reste actif et que le pere et le fils vont tripatouiller les memes choses ( sockets essentiellement ).

    si tu forkes pour tuer le pere, pourquoi forker si tu peux tout redemarrer autrement ( du genre reinitialisation propre ) ?

    l'idée serait de démarrer le démon, et que si il y a l'option du genre --interactif ... il demarre et forke un processus fils qui ne fait que de la GUI et qui communique avec pere ( via pipe/socket/pigeon-voyageur/... ) pour lui passer les ordres et recevoir les informations regulierement. ainsi, si tu fermes le processus fils le demon reste, si tu veux reouvrir la GUI tu envoies "le bon signal genre SIGUSR1" qui reforke et reouvre la GUI. ne pas oublier de prévoir un bouton "tuer le pere" dans la GUI ;)
    • [^] # Re: pas clair ...

      Posté par  . Évalué à 2.

      Merci pour ton aide, je vais tenter d'être plus clair :

      L'idée est de permettre à l'utilisateur de lancer un dæmon sur commande, grace à un clic.

      Plus précisément, je fais une application (un jeu) qui peut être à la fois serveuse ou cliente dans le sens où elle embarque tout le code nécessaire aux deux fonctions, parce que le tout reste très concis, et que c'est nettement moins contraignant pour l'utilisateur que d'avoir deux exécutables. Cependant, elle ne remplit jamais les deux rôles à la fois : elle est soit cliente, soit serveuse. Quant au serveur proprement dit, il doit naturellement se détacher de la console, aller se rattacher à init et évidement n'utilise aucune interface graphique.

      Je pense également que le moyen le plus propre de s'en sortir est effectivement de placer la boucle GTK dans un processus propre et de faire tout le travail sérieux en dehors, mais cela me fait suer de lancer deux processus simplement pour gérer une interface graphique de base.

      Merci quand même.
      • [^] # Re: pas clair ...

        Posté par  (site web personnel) . Évalué à 2.

        Pourquoi ? C'est la solution la plus propre de faire deux processus ! Surtout si par la suite tu t'apercois que par exemple tu aimerais faire tourner le serveur et la gui avec un utilisateur différent (le serveur avec un utilisateur dedie et la gui avec l'utilisateur courant qui administre le serveur). Je ne vois pas du tout le probleme d'avoir deux process ...
        • [^] # Re: pas clair ...

          Posté par  . Évalué à 2.

          Deux processus distincts, un pour le client, un pour le serveur, oui.

          Mais être obligé de créer deux processus pour la partie cliente simplement pour éviter d'hériter de GTK au moment où je forke, ça, ça m'ennuie.

          D'une manière générale, le multithreading est très bien, mais c'est souvent un moyen de pallier une conception douteuse. C'est un peu comme mettre un exit(0) au milieu d'un programme, là où des if() imbriqués auraient parfaitement résolu le problème.
          • [^] # Re: pas clair ...

            Posté par  . Évalué à 3.

            Tu n'est pas obligé de créer deux processus pour la partie cliente.

            En réorganisant un peu ton code tu devrait pouvoir le découper en trois parties:
            - code commun au client et au serveur
            - code spécifique au client (le seul utiliser GTK)
            - code spécifique au serveur

            A l'édition de liens, tu génères deux exécutables:
            - client = code spécifique client + code commun
            - serveur = code spécifique serveur + code commun

            Le client est donc toujours un processus unique et le serveur ne devrait plus avoir de dépendance vers GTK.

            Le client pourra alors sans problème lancer le serveur avec un fork/exec, y compris depuis une fonction callback.
            • [^] # Re: pas clair ...

              Posté par  . Évalué à 2.

              À l'édition de liens, tu génères deux exécutables :


              Eh oui ! Tout le problème vient de là.

              Je ne veux pas générer deux fichiers exécutables distincts, et par conséquent, je ne veux pas utiliser non plus de fonctions du style execv() ou autre ...

              D'un point de vue purement algorithmique, c'est tout-à-fait faisable. D'ailleurs mon application inclue deux modules : tty et gtk. Respectivement pour avoir une version texte ou graphique de l'interface, laquelle est dans le schéma général complètement détachée du moteur du jeu ou des autres modules. Il est tout-à-fait possible de forker au bon endroit avec le premier module, pour la simple raison que c'est moi qui ai le contrôle de la boucle principale. Il n'est malheureusement pas possible d'en sortir temporairement sous GTK. De plus, ce dernier module sous-tend une connexion au serveur X et la X-Lib n'aime pas du tout le multi-thread. On ne peut même pas refermer le socket inutilisé dans le processus fils, au risque de refermer complètement la connexion à X.

              On retombe toujours sur le même problème : Soit on implique directement deux threads dès le lancement de l'application, soit il faut générer - et installer - deux exécutables et faire invoquer l'un par l'autre avec un exec().

              Je pense que je vais confier le soin de forker à la fonction d'initialisation du module GTK, le considérer comme une nécessité de cette lib et éviter de compromettre le reste de l'appli pour cela.

              Merci à tous pour votre aide, en tous cas.
          • [^] # Re: pas clair ...

            Posté par  (site web personnel) . Évalué à 3.

            des if() imbriqué ? c'est bien souvent mal ca :)

            Si tu prend un ensemble de x criteres, alors l'ensemble des parties de cet ensemble de x criteres est de 2^x criteres.

            Appliqué à la programmation cela donne, il faut surtout reduire le nombre de "if", leur imbrication et augmenter leur lisibilité.

            bien souvent l'essentiel des bugs sont sur des effet de bord dans des conditions mal traitée ou pas traitées du tout. dans la liste on trouve :
            - mauvaise gestion du malloc()/free()
            - mauvaise gestion des IPC
            - explosion d'etat interdependant car le code ne permet de faire autrement dans le delai imparti ( car sinon faut tout recoder )

            si on regarde bien, il n'y a là dedans que des erreurs de conceptions ou d'implementation. ce qui m'amene a une regle que j'enonce ainsi :
            - tout programme ou bout de programme dont la couverture en condition est superieur à 5 tends necessairement à être buggé

            si tu as un doute, reprends le propos de dijkstra sur les goto. il dit les goto sont a eviter. soit, il a raison la dessus. par contre, si l'on deroule le code de tel maniere qu'il n'y ait plus de goto inconditionnel, il ne pourra rester au plus qu'un seul : celui d'une boucle infini. tous les autres goto sont sujet à des conditions prealable permettant soit de faire le goto soit de passer a l'instruction suivante.

            Aujourd'hui, il faut necessairement comprendre le propos de Dijkstra comme les conditions prealable au goto sont a eviter.
            • [^] # Re: pas clair ...

              Posté par  . Évalué à 2.

              Attention : ce qui suit est un troll.



              D'une manière générale, il est difficile de pas troller lorsque l'on évoque feu Edsger Dijkstra.

              Je sais que tu postes cela pour mon bien mais je fais partie des gens qui n'adhèrent pas automatiquement à ses idées (et je ne suis pas le seul si l'on en croit cette célèbre citation extraite de kernel/sched.c : http://www.coda.cs.cmu.edu/doc/talks/linuxvfs/tsld031.htm ). La discussion était d'ailleurs déjà très animée il y a trois ans :

              http://linuxfr.org/2002/08/09/9216.html

              Je reproche majoritairement deux choses aux disciples de Dijkstra :

              1) Tuer dans l'oeuf tout risque de discussion en assénant des vérités toutes faites du style : « It is practically impossible to teach good programming to students that have had a prior exposure to BASIC; as potential programmers they are mentally mutilated beyond hope of regeneration. ». Dijkstra devrait être au quotidien un type pas du tout facile à vivre et ne devait pas aimer que l'on remette en cause ses théories :-)

              Aujourd'hui, les gens qui le suivent considèrent les gens qui soutiennent toute théorie « déviante » comme étant nécessairement sots, ou au mieux dans l'ignorance. Cela me rappelle un peu Dan, le scientifique illogique :-)

              Quand on en arrive à de telles extrémités, c'est en général par manque de pertinence de l'argumentation.

              2) Raisonner de manière essentiellement mathématique. J'entends par là : tenter d'appliquer le modèle de raisonnement et l'analyse des problèmes traditionnels à l'informatique. Il faut bien se rendre compte qu'algorithmie et programmation sont deux domaines sensiblement différents et que ce n'est pas parce Dijkstra a brillament résolu le problème du colporteur que la manière dont il va l'implémenter va être propre.


              bien souvent l'essentiel des bugs sont sur des effet de bord dans des conditions mal traitée ou pas traitées du tout. dans la liste on trouve :
              - mauvaise gestion du malloc()/free()
              - mauvaise gestion des IPC
              - explosion d'etat interdependant car le code ne permet de faire autrement dans le delai imparti ( car sinon faut tout recoder )


              ... et Dieu tue un chaton aussi. Ces exemples sont les problèmes classiques récurrents de la programmation système. On les attribue à toutes les causes possibles et imaginables quand on a envie de se faire le détracteur d'une méthode particulière.

              On ne doit pas imbriquer nos if() de la même manière car moi, au contraire, je tiens cette méthode pour être la plus élégante façon de résoudre ces problèmes, spécialement ceux des malloc(). C'est même la seule chose qui me réconcilie un peu avec Dijkstra. La sacro-sainte programmation structurée ne trouve sa réelle signification que sous cette forme. Tout ce qui est conditionné par un if() doit se trouver à l'intérieur.

              Il y a belle lurette que grâce à cela, je n'utilise plus exit() et qu'il n'y a qu'un seul return, toujours à la fin de mes fonctions.

              si on regarde bien, il n'y a là dedans que des erreurs de conceptions ou d'implementation. ce qui m'amene a une regle que j'enonce ainsi :
              - tout programme ou bout de programme dont la couverture en condition est superieur à 5 tends necessairement à être buggé


              Moi, j'en assène une autre, attribuée à Euclide de Mégare et qui orne le portail mathématique du Wikipédia français :

              « Ce qui est affirmé sans preuve peut être nié sans preuve »

              Quant à la lisibilité, l'important est de garder de la cohérence tout au long de son propre code. Le reste n'est qu'affaire de subjectivité. Il y a de fortes chances pour qu'un code lisible selon tes critères soit parfaitement obscur pour quelqu'un d'autre. Moi, je pense que lorsque l'on est trop à cheval sur la forme, c'est que l'on ne l'est pas assez sur le fond.

              si tu as un doute, reprends le propos de dijkstra sur les goto


              Ben voyons, je parle de if() imbriqués et tu me parles de gotos ? Comme je le dis au dessus, il me semble que l'inclusion des différentes routines est justement le meilleur moyen de s'en débarrasser. Sémantiquement parlant, un analyseur de code (autre grand sujet de troll et d'étude en algorithmie) sera immédiatement capable de reconnaitre si un bloc d'instruction est dépendant d'un if() ou pas. Si on les remet à plat, on perd cette possibilité.

              Aujourd'hui, il faut necessairement comprendre le propos de Dijkstra comme les conditions prealable au goto sont a eviter.


              Oui, mais ce n'est pas suffisant. Il faut également le saisir de la manière dont il a voulu l'exprimer. Jamais un troll en informatique n'aura été si proche d'une guerre de religion. Dijkstra était déjà un fondamentaliste, mais la plupart des intégristes interprètent aujourd'hui ses propos selon le sens qui leur plaît et partent en croisade contre tous les autres.

              Dijkstra a produit beaucoup de bon matériel, mais il faudrait voir à ne pas prendre tout ce qu'il a dit comme paroles d'évangile.




              Tout ceci étant dit, je te remercie quand même d'avoir pris le temps de te pencher sur mon problème (d'une part) et tenter de m'éclairer (d'autre part).
      • [^] # Re: pas clair ...

        Posté par  (site web personnel) . Évalué à 0.

        Et tu ne veux pas tout simplement faire un script SH qui parse un argument en ligne de commande indiquant quel exécutable lancer ? (en plus tu peux directement daemoniser le lancement de ton exécutable serveur...)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.