2009-12-09 8 views
3

PreludeL'écriture dans une socket est une limitation arbitraire de l'appel système sendfile()?

sendfile() est un syscall extrêmement utile pour deux raisons:

D'abord, il est moins de code qu'un read()/write() (ou recv()/send() si vous préférez que jive) boucle.
Deuxièmement, il est plus rapide (moins de syscalls, l'implémentation peut copier entre les périphériques sans tampon, etc ...) que les méthodes susmentionnées.

Code moins. Plus efficace. Impressionnant.

Sous UNIX, tout est (principalement) un fichier. C'est le territoire laid de la collision de la théorie platonique et de la pratique du monde réel. Je comprends que les sockets sont fondamentalement différents des fichiers résidant sur certains appareils. Je n'ai pas exploré les sources de Linux/* BSD/Darwin/quel que soit le système d'exploitation implémente sendfile() pour savoir pourquoi ce syscall spécifique est limité à l'écriture sur des sockets (en particulier, les sockets de streaming).

Je veux juste savoir ...

Question

Ce qui est limite sendfile() de permettant le descripteur de fichier de destination pour être autre chose qu'un socket (comme un fichier de disque, ou un tuyau)?

+0

En 2.6.33 et plus tard, l'argument out_fd pour sendfile peut être n'importe quel fd (pas seulement un socket). – ldrg

Répondre

3

Fondamentalement, la seule chose qui le limite est que "personne n'a encore écrit le code". Cependant, je comprends que la raison pour laquelle les non-inscrits ont écrit le code pour les deux cas que vous mentionnez est qu'ils nécessiteraient tous deux la copie des données, ce qui supprime en grande partie l'avantage d'utiliser sendfile.

  • Pour un fichier à fichier sendfile, vous auriez besoin d'une copie parce que sinon la même page devrait être dans le pagecache à la fois comme une page propre dans le fichier source et une page sale dans la destination fichier. Je ne pense pas que le pagecache soit construit pour gérer ce cas pour le moment (bien que, bien sûr, cela pourrait être changé s'il y avait suffisamment de motivation). Pour un sendfilesendfile file-to-pipe, vous avez besoin d'une copie, car le processus de destination doit obtenir une copie privée et inscriptible des données. Quoi qu'il en soit, pour la plupart des utilisations de ce cas, nous avons déjà mmap.

4

Je crois me souvenir que c'était une limitation introduite au début de Linux 2.6 (2.4 n'avait pas la limitation).

Depuis la version 2.6.17 Linux a l'appel système splice() qui est similaire; plus flexible, mais légèrement moins efficace. Linus a parlé de ré-implémenter sendfile en termes de splice(). Voir http://kerneltrap.org/node/6505