On Tuesday 10 November 2009 10:57:00 Philippe Strauss wrote: > L'autre idée discutée hier soir avec des amis c'est SysV IPC, un ségment > de mémoire partagée.
OK, Je pense comprendre ton probleme... Les "pipes" du kernel (le probleme avec les sockets est encore plus complexe) sont des buffers temporaires. Par defaut leur taille est de 8K. A priori, si tout va bien, un write() dans un pipe va engendrer un "signal" (kernel internal) pour l'autre process en attente de lecture. Donc, les donnees ne devraient etre dans le buffer que pendant un laps de temps tres court. Ce laps de temps peut aller de quelques dizaines de nanosecondes a... quelques dizaines de microsecondes (en moyenne). Mais, cette valeur ne peut pas etre determinee car elle depend d'un tres grand nonbres de parametres independants du processus. Tout au plus peut-on estime une valeur statistique moyenne avec une variance, mais sans plus... N'oublions pas, nosu ne sommes pas dans un environement de kernel temps-reel ! Ceci dit, pourquoi les fonctions habituelles (fstat etc.) ne peuvent elles pas me donner la quantite de bytes contenus dans le buffer ? Simplement parcequ'entre le moment ou l'on a ecrit ces donnees et le moment ou l'on effectue un fstat, il y a des chances que ces donnees ne soient plus la... N'oublions pas, 2 context-swicth dans ce cas... C'est le process-scheduler du kernel qui decide quel(s) process doit(vent) extre execute losr d'un context switch. Les algorithmes dans ce domaine subissent des modifications continuelles et on ne peut se baser sur les regles en vigueurs car ces regles evoluent continuellement d'une version du kernel a l'autre. On ne peut donc pas compter sur les "pipes" comme outil de gestion de flux, car il est impossible de determiner la situation exacte a un instant t. Il est donc necessaire de developer une solution ad-hoc pour ton probleme. On doit developer un module "buffer" avec des methodes specifiques. Ces methodes seront chargees d'assurer une synchronisation temporelle entre l'entree et la sortie. Ce buffer doit pouvoir etre acceder par N flux en entree et (je pense) un flux en sortie. La synchronisation entre ecriture et lecture doit etre assuree par des semaphores, afin de "bloquer" l'acces pendant des operations de modifiaction des meta-donnees de chaque bloc de bytes. Sans doute le meilleur moyen d'assurer cette echange peut etre effectue a l'aide de "memory maped files" (see mmap()). Pourquoi des mmap plutot que des "Shared memory" (shm) ? Simplement parceque la gestion des phases de transitions (creation/destruction) est plus facile a gerer avec des mmap qu'avec des shm. De plus, les mmap etant relies au "file-system", il est plus facile de gerer les "locks" de regions et le contenu lorsque le process "createur" a disparu. Avec des shm, il faut aussi se taper la gestion des semaphores (sem), qui posent eux-aussi leurs problemes, J'ai pas mal bosser sur des partages de shm entre plusieurs process et la gestion de la phase de creation est complexe. Si l'on rajoute a cela qu'en meme temps il faut creer les semaphores (semop()) en s'assurant qu'aucun autre process ne fait la memem chose... c'est un peu touchy :-) Avec des mmap, c'est beaucoup plus simpel car on peut utiliser les fonctions de lock du file-systeme pour proteger les zones de modifiaction des meta-donnees. Autre avantage, lors de la disparition d'un process, les lock que celui-ci aurait effectue seront "nettoyes" par la gestion du file-system. Dans le cas des shm/sem, les semaphores restent dans un etat determine et on arrive facilement a des situation de blocage et le "nettoyage" s'avere souvent complexe. Donc, tu implementes une librairie de lecture/ecriture de paquest de donnees dans un mmap() en mode FIFO... Tu peux t'octroyer des buffers de grande taille que tu peux gerer librement. La gestion du "timimg" se fait alors a un plus haut niveau... soit al'ecriture qui decide d'ecraser un bloc qui ne devrait plus etre la, soit a la lecture en decidant d'ignorer le bloc le plus ancien... cela depend de la strategie que l'on veut mettre en place. L'autre avantage est la possibilite de faire de tres gros buffer permettant d'introduire la notion de "delay" ou de multi-serveurs... Les donnees, une fois ecrites par la partie "flux-entrant" vont finir par etre ecrites sur le disque (de maniere transparente) et le(s) process de lecture lira ses donnees du disque (aussi de maniere transparente). Bref, tous les avantages. N'oublions pas non-plus que les mmap() utilisent (au niveau kernel) la meme architecture/technique que les segments de shared-memory. Experience faite, la gestion des semaphores peut s'averer tres complexes dans les phases transitoires et on obtiens les memes performances avec des mmap() sans en avoir les inconvenients. En effet, si les buffers ne sont pas trop gros, il y a toutes les chances que les donnees ne restent qu'en memoire et n'aillent jamais se promener sur le disque. Mais, meme la, les vitesses de lecture des disques permettent largement de faire de l'audio et/ou de la video. dc _______________________________________________ gull mailing list [email protected] http://forum.linux-gull.ch/mailman/listinfo/gull
