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

x86 32-bits / 64-bits Assembleur Discussion :

shmget ou pipe ?


Sujet :

x86 32-bits / 64-bits Assembleur

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 407
    Par défaut shmget ou pipe ?
    Salut,

    J'aimerais savoir quelle est la meilleure méthode entre deux lorsque les deux peuvent fonctionner ?
    Meilleure en niveau performance, et aussi fiabilité..

    Niveau performance, je ne compte pas faire un test de performance, car avec du multithread je ne pense pas que ce serait fiable.
    Mais à voir comme ça je dirais que la méthode pipe sera moins performance, de part le simple faite que je sois obligé de coder plusieurs "write" et "read".
    En tout cas j'ai été agréablement surpris par ce systême. Tellement simple et efficace.

    Pour shmget, pas 50 "write" et "read" à coder, donc ça allège pas mal le code.
    En dehors de ça, il faut que je termine ma deuxième version de code avec cette méthode pour voir concretement ce que ça donne, mais pour l'instant ça fonctionne bien.

    En faite, ce que je ne voudrais pas, c'est finir complètement mon code (environ 1000 lignes lorsqu'il le sera) avec l'une ou l'autre méthode, et au final m'apercevoir qu'il y a des bugs dans certaines conditions.
    Pour ça que j'aimerais connaître la méthode la plus fiable, même si les bugs peuvent être possible pour les deux.

    Le multhreading, c'est nouveau pour moi, et donc encore assez nébuleux.
    Là je m'y suis mis simplement par obligation pour ce code. Il s'agit de ma pile tcp que j'avais commencé (en style statique) et que je dois finir en style dynamique..
    En gros ça donne ça;

    - Thread n°1: gestion réception et envoie des segments tcp, et envoie de la partie "tcp-data" des segments réceptionnés au second thread, qui en fait ce qu'il veut.

    - Thread n°2: Fonctionne comme n'importe quel programme qui contient une partie réseau avec l'api "recv" ou "send" en mode "sock_stream". Donc il envoit également la partie "tcp-data" au thread n°1 qui s'occupe de la placer dans un segment tcp pour l'envoyer sur le réseau.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 407
    Par défaut
    Finalement j'ai opté pour shmget.
    J'ai pu réduire gravement la taille du code.
    Et c'est beaucoup plus lisible.
    Juste un peu galère au niveau de l'écriture du code, puisqu'il faut mettre des addresses de mémoire dans des buffers, et donc ne pas confondre entre les adresses des buffers et les adresses de la mémoire.
    En dehors de ça, c'est tout de même beaucoup plus clair.
    Je pourrais aussi re-déplacer de la mémoire partagé vers des buffers de la mémoire du thread en cours, ça simplifirait l'écriture du code par la suite, mais bon, c'est faire une chose inutile juste pour simplifier le coding et j'aime pas ça.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 407
    Par défaut
    Re-finalement, shmget est inutilisable dans mon cas.
    Il fait surchauffer le proc à mort. Toujours un core à 100%
    Heureusement que je m'en suis aperçu avant d'aller plus loin.

    J'ai testé avec mon code version pipe, aucun problème, le proc ne bouge pas d'un millimètre.

    Et c'est vraiment la seule est unique différence entre les deux codes.
    Alors après je ne sais pas si c'est un bug quelconque, ou si il ne faut pas utiliser la shmem dans des boucles. Mais si c'est les boucles le problème, alors c'est mort car je ne peux pas faire de transfert shmem hors de ces boucles. Mon code fait que c'est impossible. Je pourrais le faire uniquement après les boucles, donc aucun intérêt.

    J'ai même tenté des nanosleep, mais c'est impossible.
    100 ms, ça ne reçoit plus rien, logique
    10 ms ça reçoit avec un énorme décalage, et le proc remonte à 100%.

    edit: C'est forcément les boucles, puisque le proc ne bouge plus avec un nanosleep à 100ms. Boucles qui sont identiques avec les pipes, et en mode non-bloquant, avec beaucoup plus de ligne de code (pour les "read et "write"). Donc c'est forcément la shmem dans les boucles qui cause ce problème.

    Bref ça fonctionne niquel avec les pipes, donc je vais revenir à ça, même si c'est lourd à coder.

    Galère quand même tout ça.
    Depuis un moment je commence à comprendre les gens qui font leur propre OS.
    C'est the ultime solution pour être tranquille.
    Car on est jamais mieux servi que par sois-même ^

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 485
    Par défaut
    Hello,

    Citation Envoyé par n5Rzn1D9dC Voir le message
    Re-finalement, shmget est inutilisable dans mon cas.
    Il fait surchauffer le proc à mort. Toujours un core à 100%
    Heureusement que je m'en suis aperçu avant d'aller plus loin.
    Tu travailles avec quel système d'exploitation ?

    « shmget » signifie « Get a segment of SHared Memory ». Il est certain que la mémoire partagée est de loin la méthode la plus efficace — en local sur une machine donnée — puisque le système d'exploitation n'a absolument rien à faire une fois le segment alloué.

    Par contre, un tube est « bloquant », c'est-à-dire que c'est le système d'exploitation qui garde la main tant qu'il n'y a rien à lire dedans. Et comme c'est lui aussi qui gère les stats du processeur et qui, éventuellement, contrôle en conséquence l'échelonnement en fréquence, il va forcément faire cela au mieux si tu lui laisses la main. Si ton CPU tourne à 100 %, c'est parce que tu fais une attente active.

    Si tu travailles avec les IPC SysV, le mécanisme par excellence pour gérer les accès concurrents est les sémaphores : semget().

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 407
    Par défaut
    Salut,

    Je suis sous Debian testing.

    Oui j'avais pensé à tester les sémaphores, ça fait plusieurs fois que je vois des commentaires positifs sur ça, mais le problème c'est qu'il y a deux boucles:
    - Dans le thread 1 pour gérer la réception des segments tcp via un "read"
    - Dans le thread 2 pour contrôler la partie "tcp-data" envoyé par le thread 1.

    Mais pour celle du thread 1, il n'y a pas de shmem dans la boucle, c'est ça qui est étrange..
    Du coup je m'étais dit que ça ne changerait rien étant donné que le problème est lié aux deux boucles.. (ça ne le fait plus avec un nanosleep de 100ms sur les deux boucles).

    Par contre, aucun problème avec les pipes, même pour celle du thread 1, qui est non-bloquante.
    J'ai fait plusieurs tests avec les pipes, et apparemment (en tout cas sur mon systême), il n'y a que les "read" coté parent qui sont bloquant si vide. Et mon thread 1 est enfant.

    edit: c'est un code avec fork.

    Pour ça que je n'ai pas trop compris.
    Pour la boucle du thread 1, il n'a pas d'accès shmem, donc pourquoi le proc s'affole ? Aucune idée.

    J'avais aussi pensé à faire un "pause" / "sigaction" avant de me rendre compte tout fonctionnait parfait avec le code pipe.
    Je n'ai pas besoin de faire de portabilité, c'est un code juste pour moi, donc je me demandais si ce ne serait pas suffisant plutôt que d'utiliser une sémaphore.

    Je vais re-testé quand même voir si je n'ai raté quelque chose.

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 485
    Par défaut
    Citation Envoyé par n5Rzn1D9dC Voir le message
    Re-finalement, shmget est inutilisable dans mon cas.
    Il fait surchauffer le proc à mort. Toujours un core à 100%
    Heureusement que je m'en suis aperçu avant d'aller plus loin.

    J'ai testé avec mon code version pipe, aucun problème, le proc ne bouge pas d'un millimètre.
    Comme dit plus haut, je ne pense pas que ce soit dû en soi à shmget(). Quand tu utilises des pipes, ils sont bloquants, donc la question ne se pose pas. Dès que tu passes à de la mémoire partagée, il n'y a plus rien pour bloquer ta boucle en soi, donc elle tourne en permanence. Il faut donc passer la main au système quand il n'y a rien à faire et la récupérer au bon moment. Il s'agit donc de conception en amont, et de l'utilisation de l'outil approprié en conséquence.

    Bref ça fonctionne niquel avec les pipes, donc je vais revenir à ça, même si c'est lourd à coder.
    Si tes données sont courtes, c'est effectivement ce qu'il y a de mieux puisqu'on peut transmettre l'info en même temps qu'on débloque le processus. Si elles sont longues, en revanche, il vaut mieux utiliser un pipe ou un sémaphore uniquement pour débloquer le processus et laisser celui-ci chercher ce dont il a besoin dans la mémoire partagée.

    Depuis un moment je commence à comprendre les gens qui font leur propre OS.
    C'est the ultime solution pour être tranquille.
    Car on est jamais mieux servi que par sois-même ^
    Mouais. Créer son propre OS est très stimulant, c'est certain, mais l'emmener à terme et le maintenir ensuite devient très rébarbatif. Personnellement, j'ai arrêté de penser à cela quand j'ai commencé à toucher à UNIX. D'abord parce que je me suis rendu compte que tout ce à quoi j'avais pu penser sur le plan structurel existait déjà dans ce système, y compris des choses que je n'aurais jamais osé espérer sous D.O.S. ou Windows, comme les liens durs du système de fichiers.

    Avec cela, comme c'est un système qui existe depuis l'aube de l'informatique, ce qui est important pour moi qui suis de la génération 1980, que c'est extrêmement stable, que ça a été lancé par des pontes de l'informatique théorique comme Denis Ritchie, Ken Thompson et Kernigan, que ce sont les mêmes qui ont lancé le langage C, que même MacOS converge vers ça aujourd'hui et que, cerise sur le gâteau, les distribs de Linux et de BSD sont gratuites, communautaires, collaboratives et complètement open source, j'ai vite été convaincu du fait que s'il faut s'investir dans un framework, c'est celui-ci.

    C'est toujours intéressant de visiter osdev et autres recueils du genre pour partir zéro, bien sûr. Mais de temps en temps, j'aimerais bien que ce soit sur des architectures autres que celle du PC (qui avec cela est probablement l'une des plus mauvaises jamais conçues). L'époque des huit et seize bits me manque pour cela.

    Citation Envoyé par n5Rzn1D9dC Voir le message
    Oui j'avais pensé à tester les sémaphores, ça fait plusieurs fois que je vois des commentaires positifs sur ça, mais le problème c'est qu'il y a deux boucles:
    - Dans le thread 1 pour gérer la réception des segments tcp via un "read"
    - Dans le thread 2 pour contrôler la partie "tcp-data" envoyé par le thread 1.
    Je ne sais pas si tu le sais déjà ou pas mais si c'est cela qui t'ennuie, il existe select() pour surveiller plusieurs descripteurs à la fois dans un même fil.


    Je n'ai pas besoin de faire de portabilité, c'est un code juste pour moi, donc je me demandais si ce ne serait pas suffisant plutôt que d'utiliser une sémaphore.
    Un sémaphore. « Sémaphore » est masculin. ;-)

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 07/04/2006, 13h35
  2. Pipes - Comment faire ?
    Par Neitsa dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 11/12/2003, 05h44
  3. [C/S] Boken Pipe
    Par Gogoye dans le forum POSIX
    Réponses: 4
    Dernier message: 23/10/2003, 10h48
  4. Réponses: 3
    Dernier message: 21/08/2003, 14h47
  5. Problème : bloquage d'un pipe
    Par Nicaisse dans le forum POSIX
    Réponses: 10
    Dernier message: 24/07/2003, 11h06

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