Bonjour à tous, parlons aujourd'hui de la technologie Linux zéro copie. Nous utiliserons l'appel système sendfile comme point d'entrée pour explorer en profondeur les principes de base de la technologie zéro copie. L'idée principale de la technologie zéro copie est de minimiser la copie des données entre les mémoires et d'améliorer l'efficacité et les performances de la transmission des données en optimisant le chemin de transmission des données.
La technologie Linux zéro copie est une technologie utilisée pour optimiser la transmission de données. Elle améliore l'efficacité de la transmission de données en réduisant le nombre de copies de données entre le mode noyau et le mode utilisateur.
Pendant le processus de transmission des données, il est généralement nécessaire de copier les données du tampon du noyau vers le tampon d'application, puis du tampon d'application vers le tampon du périphérique réseau avant que l'envoi puisse être terminé.
L'avantage de la technologie zéro copie est qu'elle peut transmettre directement des données sans avoir besoin d'étapes de copie intermédiaires, ce qui contribue à améliorer l'efficacité de la transmission des données.
Mise en œuvre de la technologie Linux zéro copie :
L'appel système sendfile peut transférer les données du fichier directement dans l'espace du noyau. Il le fait en copiant les données d'un descripteur de fichier vers le tampon d'envoi d'un autre descripteur de fichier. De cette manière, les données peuvent être envoyées directement via la pile de protocoles réseau, évitant ainsi les opérations fréquentes de copie de données entre l'espace utilisateur et l'espace noyau.
Cela évite la copie de données entre le noyau et l'espace utilisateur et améliore l'efficacité de la transmission.
prototype de fonction d'appel système sendfile :
#include ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); 参数说明: out_fd:目标文件描述符,用于发送数据。 in_fd:源文件描述符,从该文件读取数据。 offset:指定从源文件的哪个位置开始读取数据,可以为NULL表示从当前位置开始。 count:要传输的字节数。 返回值: 成功:返回写入out_fd文件的字节数。 失败:返回-1,并设置errno。
Pour envoyer un fichier via socket en utilisant la méthode traditionnelle, nous devons exécuter un chemin relativement long.
Chemin : Disque -> Cache de la page de fichiers -> Tampon utilisateur -> Tampon de socket -> Carte réseau.
La situation du changement de contexte et de la copie mémoire est la suivante :
Photos
Utilisez sendfile pour envoyer des fichiers, le chemin complet sera relativement plus court.
Chemin : Disque -> Cache de la page de fichiers -> Tampon de socket -> Carte réseau.
La situation du changement de contexte et de la copie mémoire est la suivante :
Changement de contexte : 2 fois (appel sendfile, retour sendfile)
Copie DMA : 2 fois
Copie CPU : 1 fois (Cache de page de fichiers -> Socket Buffer)
Photos
Le cœur de l'implémentation de sendfile est constitué de tubes, qui sont largement utilisés dans les systèmes Linux, tels que la communication inter-processus via des tubes.
Lorsque les données du fichier doivent être copiées dans le tampon du socket, un canal (tampon en anneau) sera temporairement créé, les données du fichier seront d'abord copiées dans le canal, puis les données du canal seront migrées vers le tampon du socket Migration des données. n'est pas une copie de données, mais un pointeur sur l'adresse mémoire.
Photos
En utilisant sendfile pour envoyer des fichiers, nous pouvons réduire deux changements de contexte et une copie du processeur. Si notre scénario d'application actuel nécessite l'envoi d'un grand nombre de fichiers, l'utilisation de sendfile peut considérablement améliorer les performances du système.
Les tuyaux sont largement utilisés dans les systèmes Linux. En plus de la technologie zéro copie utilisant des tuyaux, la communication inter-processus utilise également des tuyaux. Alors, que sont exactement les tuyaux ?
Photos
Qu'est-ce qu'un pipeline ?
Un tube est en fait un tampon en anneau, à travers lequel les données peuvent être copiées d'un fichier à un autre.
Le tube est défini par la structure struct pipe_inode_info. Cette structure de données comporte 4 membres importants :
Le pipe buffer est défini par struct pipe_buffer, qui compte 3 membres importants :
Juger si le tuyau est plein ou vide ?
Jugement que le pipeline est plein :
head – tail >= ring_size, indiquant que le tuyau est plein.
Jugement si le tuyau est vide :
head == tail, indiquant que le tuyau est vide.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!