Table des matières
citation" >citation
什么是零拷贝技术(zero-copy)?" >什么是零拷贝技术(zero-copy)?
使用 mmap" >使用 mmap
使用sendfile" >使用sendfile
使用splice" >使用splice
Maison Opération et maintenance exploitation et maintenance Linux Une brève analyse de la technologie zéro copie sous Linux

Une brève analyse de la technologie zéro copie sous Linux

Aug 04, 2023 pm 04:23 PM
linux 拷贝


Cet article traite des principales technologies zéro copie et des scénarios applicables de la technologie zéro copie sous Linux. Afin d'établir rapidement la notion de zéro copie, nous introduisons un scénario couramment utilisé :

citation

Lors de l'écriture d'un programme serveur (Serveur Web ou serveur de fichiers), le téléchargement de fichiers est une fonction de base. A ce stade, la tâche du serveur est d'envoyer les fichiers dans le disque hôte du serveur depuis le socket connecté sans modification. Nous utilisons généralement le code suivant pour le compléter :

while((n = read(diskfd, buf, BUF_SIZE)) > 0)
    write(sockfd, buf , n);
Copier après la connexion

L'opération de base consiste à lire les fichiers depuis le. disque dans une boucle de contenu vers le tampon, puis envoyer le contenu du tampon vers le socket. Cependant, les opérations d'E/S Linux sont par défaut des E/S mises en mémoire tampon. Les deux principaux appels système utilisés ici sont la lecture et l'écriture. Nous ne savons pas ce que le système d'exploitation y fait. En fait, plusieurs copies de données ont eu lieu lors des opérations d'E/S ci-dessus.

Lorsqu'une application accède à un certain élément de données, le système d'exploitation vérifiera d'abord si le fichier a été accédé récemment et si le contenu du fichier est mis en cache dans le tampon du noyau. Si tel est le cas, le système d'exploitation utilisera directement le buf. fourni par l'appel système de lecture Address, copiez le contenu du tampon du noyau dans le tampon de l'espace utilisateur spécifié par buf. Sinon, le système d'exploitation copie d'abord les données du disque dans le tampon du noyau. Cette étape repose actuellement principalement sur DMA pour la transmission, puis copie le contenu du tampon du noyau dans le tampon utilisateur.

Ensuite, l'appel système d'écriture copie le contenu du tampon utilisateur dans le tampon noyau lié à la pile réseau, et enfin le socket envoie le contenu du tampon noyau à la carte réseau. Cela dit, regardons l'image pour la rendre plus claire :

Une brève analyse de la technologie zéro copie sous Linux

Copie des données

从上图中可以看出,共产生了四次数据拷贝,即使使用了DMA来处理了与硬件的通讯,CPU仍然需要处理两次数据拷贝,与此同时,在用户态与内核态也发生了多次上下文切换,无疑也加重了CPU负担。

在此过程中,我们没有对文件内容做任何修改,那么在内核空间和用户空间来回拷贝数据无疑就是一种浪费,而零拷贝主要就是为了解决这种低效性。

什么是零拷贝技术(zero-copy)?

零拷贝主要的任务就是避免CPU将数据从一块存储拷贝到另外一块存储,主要就是利用各种零拷贝技术,避免让CPU做大量的数据拷贝任务,减少不必要的拷贝,或者让别的组件来做这一类简单的数据传输任务,让CPU解脱出来专注于别的任务。这样就可以让系统资源的利用更加有效。

我们继续回到引文中的例子,我们如何减少数据拷贝的次数呢?一个很明显的着力点就是减少数据在内核空间和用户空间来回拷贝,这也引入了零拷贝的一个类型:

让数据传输不需要经过 user space。

使用 mmap

我们减少拷贝次数的一种方法是调用mmap()来代替read调用:

buf = mmap(diskfd, len);
write(sockfd, buf, len);
Copier après la connexion

应用程序调用mmap(),磁盘上的数据会通过DMA被拷贝的内核缓冲区,接着操作系统会把这段内核缓冲区与应用程序共享,这样就不需要把内核缓冲区的内容往用户空间拷贝。应用程序再调用write(),操作系统直接将内核缓冲区的内容拷贝到socket缓冲区中,这一切都发生在内核态,最后,socket缓冲区再把数据发到网卡去。同样的,看图很简单:

Une brève analyse de la technologie zéro copie sous Linux

mmap

L'utilisation de mmap au lieu de read réduit évidemment une copie. Lorsque la quantité de données copiées est importante, cela améliore sans aucun doute l'efficacité. Mais l’utilisation de mmap a un coût. Lorsque vous utilisez mmap, vous pouvez rencontrer des pièges cachés. Par exemple, lorsque votre programme mappe un fichier, mais que le fichier est tronqué (tronqué) par un autre processus, l'appel système d'écriture se terminera par le signal SIGBUS car il accède à une adresse illégale. Le signal SIGBUS tuera votre processus par défaut et générera un coredump. Si votre serveur est arrêté de cette manière, cela entraînera une perte.

Habituellement, nous utilisons les solutions suivantes pour éviter ce problème :

1. Créez un gestionnaire de signal pour le signal SIGBUS

Lorsqu'un signal SIGBUS est rencontré, le gestionnaire de signal revient simplement et l'appel système d'écriture is Le nombre d'octets écrits avant d'être interrompu sera renvoyé et errno sera défini sur succès, mais c'est une mauvaise approche car vous ne résolvez pas le cœur du problème.

2. Utiliser le verrouillage de bail de fichier

Habituellement, nous utilisons cette méthode pour utiliser un verrou de bail sur le descripteur de fichier. Nous demandons un verrouillage de bail au noyau pour le fichier lorsque d'autres processus souhaitent tronquer le fichier. , Le noyau nous enverra un signal RTSIGNALLEASE en temps réel pour nous indiquer que le noyau détruit le verrou en lecture-écriture que vous avez placé sur le fichier. De cette façon, votre appel système d'écriture sera interrompu avant que le programme n'accède à la mémoire illégale et ne soit tué par SIGBUS. write renverra le nombre d'octets écrits et définira errno sur succès.

Nous devons verrouiller le fichier mmap avant et le déverrouiller après avoir utilisé le fichier :

if(fcntl(diskfd, F_SETSIG, RT_SIGNAL_LEASE) == -1) {
    perror("kernel lease set signal");
return -1;
}
/* l_type can be F_RDLCK F_WRLCK  加锁*/
/* l_type can be  F_UNLCK 解锁*/
if(fcntl(diskfd, F_SETLEASE, l_type)){
    perror("kernel lease set type");
return -1;
}
Copier après la connexion

使用sendfile

从2.1版内核开始,Linux引入了sendfile来简化操作:

#include<sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
Copier après la connexion

系统调用sendfile()在代表输入文件的描述符infd和代表输出文件的描述符outfd之间传送文件内容(字节)。描述符outfd必须指向一个套接字,而infd指向的文件必须是可以mmap的。这些局限限制了sendfile的使用,使sendfile只能将数据从文件传递到套接字上,反之则不行。

使用sendfile不仅减少了数据拷贝的次数,还减少了上下文切换,数据传送始终只发生在kernel space。

Une brève analyse de la technologie zéro copie sous Linux

sendfile系统调用过程

在我们调用sendfile时,如果有其它进程截断了文件会发生什么呢?假设我们没有设置任何信号处理程序,sendfile调用仅仅返回它在被中断之前已经传输的字节数,errno会被置为success。如果我们在调用sendfile之前给文件加了锁,sendfile的行为仍然和之前相同,我们还会收到RTSIGNALLEASE的信号。

目前为止,我们已经减少了数据拷贝的次数了,但是仍然存在一次拷贝,就是页缓存到socket缓存的拷贝。那么能不能把这个拷贝也省略呢?

借助于硬件上的帮助,我们是可以办到的。之前我们是把页缓存的数据拷贝到socket缓存中,实际上,我们仅仅需要把缓冲区描述符传到socket缓冲区,再把数据长度传过去,这样DMA控制器直接将页缓存中的数据打包发送到网络中就可以了。

总结一下,sendfile系统调用利用DMA引擎将文件内容拷贝到内核缓冲区去,然后将带有文件位置和长度信息的缓冲区描述符添加socket缓冲区去,这一步不会将内核中的数据拷贝到socket缓冲区中,DMA引擎会将内核缓冲区的数据拷贝到协议引擎中去,避免了最后一次拷贝。

Une brève analyse de la technologie zéro copie sous Linux

带DMA的sendfile

不过这一种收集拷贝功能是需要硬件以及驱动程序支持的。

使用splice

sendfile只适用于将数据从文件拷贝到套接字上,限定了它的使用范围。Linux在2.6.17版本引入splice系统调用,用于在两个文件描述符中移动数据:

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include<fcntl.h>
ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsignedint flags);
Copier après la connexion

splice调用在两个文件描述符之间移动数据,而不需要数据在内核空间和用户空间来回拷贝。他从fdin拷贝len长度的数据到fdout,但是有一方必须是管道设备,这也是目前splice的一些局限性。flags参数有以下几种取值:

  • SPLICEFMOVE :尝试去移动数据而不是拷贝数据。这仅仅是对内核的一个小提示:如果内核不能从pipe移动数据或者pipe的缓存不是一个整页面,仍然需要拷贝数据。Linux最初的实现有些问题,所以从2.6.21开始这个选项不起作用,后面的Linux版本应该会实现。

  • SPLICEFNONBLOCK :splice 操作不会被阻塞。然而,如果文件描述符没有被设置为不可被阻塞方式的 I/O ,那么调用 splice 有可能仍然被阻塞。

  • SPLICEFMORE : Il y aura plus de données dans les appels d'épissage ultérieurs.

L'appel splice utilise le mécanisme de tampon de canal proposé par Linux, donc au moins un descripteur doit être un canal.

Les technologies sans copie ci-dessus sont toutes mises en œuvre en réduisant la copie des données entre l'espace utilisateur et l'espace noyau, mais parfois, les données doivent être copiées entre l'espace utilisateur et l'espace noyau. Pour le moment, nous ne pouvons travailler que sur le timing de la copie des données dans l’espace utilisateur et dans l’espace noyau. Linux utilise généralement la copie en écriture pour réduire la surcharge du système. Cette technologie est souvent appelée COW.

Pour des raisons d'espace, cet article ne présente pas la copie sur écriture en détail. La description générale est la suivante : si plusieurs programmes accèdent au même élément de données en même temps, alors chaque programme dispose d'un pointeur vers cet élément de données. Du point de vue de chaque programme, il possède cet élément de données indépendamment lorsque le programme. doit Lorsque le contenu des données est modifié, le contenu des données sera copié dans le propre espace d'application du programme. Ce n'est qu'alors que les données deviendront les données privées du programme. Si le programme n'a pas besoin de modifier les données, il n'a jamais besoin de copier les données dans son propre espace d'application. Cela réduit la copie des données. Le contenu copié lors de la rédaction peut être utilisé pour rédiger un autre article. . .

De plus, il existe certaines technologies sans copie, telles que l'ajout de la marque O_DIRECT aux E/S Linux traditionnelles pour activer les E/S directes, évitant ainsi la mise en cache automatique, et la technologie immature fbufs, que cet article n'a pas encore Toutes les technologies sans copie ne sont que quelques-unes des plus courantes. Si vous êtes intéressé, vous pouvez les étudier par vous-même. Généralement, les projets côté serveur matures modifieront également les parties du noyau liées aux E/S. leurs débits de transmission de données.

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!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Impossible de se connecter à MySQL en tant que racine Impossible de se connecter à MySQL en tant que racine Apr 08, 2025 pm 04:54 PM

Les principales raisons pour lesquelles vous ne pouvez pas vous connecter à MySQL en tant que racines sont des problèmes d'autorisation, des erreurs de fichier de configuration, des problèmes de mot de passe incohérents, des problèmes de fichiers de socket ou une interception de pare-feu. La solution comprend: vérifiez si le paramètre Bind-Address dans le fichier de configuration est configuré correctement. Vérifiez si les autorisations de l'utilisateur racine ont été modifiées ou supprimées et réinitialisées. Vérifiez que le mot de passe est précis, y compris les cas et les caractères spéciaux. Vérifiez les paramètres et les chemins d'autorisation du fichier de socket. Vérifiez que le pare-feu bloque les connexions au serveur MySQL.

C compilation conditionnelle du langage: un guide détaillé pour les débutants vers des applications pratiques C compilation conditionnelle du langage: un guide détaillé pour les débutants vers des applications pratiques Apr 04, 2025 am 10:48 AM

C La compilation conditionnelle du langage est un mécanisme pour compiler sélectivement les blocs de code en fonction des conditions de temps de compilation. Les méthodes d'introduction incluent: l'utilisation des directives #IF et #ELSE pour sélectionner des blocs de code en fonction des conditions. Les expressions conditionnelles couramment utilisées incluent STDC, _WIN32 et Linux. Cas pratique: imprimez différents messages en fonction du système d'exploitation. Utilisez différents types de données en fonction du nombre de chiffres du système. Différents fichiers d'en-tête sont pris en charge selon le compilateur. La compilation conditionnelle améliore la portabilité et la flexibilité du code, ce qui le rend adaptable aux modifications du compilateur, du système d'exploitation et de l'architecture du processeur.

Quels sont les 5 composants de base de Linux? Quels sont les 5 composants de base de Linux? Apr 06, 2025 am 12:05 AM

Les cinq composants de base de Linux sont: 1. Le noyau, gérant les ressources matérielles; 2. La bibliothèque système, fournissant des fonctions et des services; 3. Shell, l'interface pour les utilisateurs pour interagir avec le système; 4. Le système de fichiers, stockant et organisant des données; 5. Applications, en utilisant des ressources système pour implémenter les fonctions.

Comment résoudre MySQL ne peut pas être démarré Comment résoudre MySQL ne peut pas être démarré Apr 08, 2025 pm 02:21 PM

Il existe de nombreuses raisons pour lesquelles la startup MySQL échoue, et elle peut être diagnostiquée en vérifiant le journal des erreurs. Les causes courantes incluent les conflits de port (vérifier l'occupation du port et la configuration de modification), les problèmes d'autorisation (vérifier le service exécutant les autorisations des utilisateurs), les erreurs de fichier de configuration (vérifier les paramètres des paramètres), la corruption du répertoire de données (restaurer les données ou reconstruire l'espace de la table), les problèmes d'espace de la table InNODB (vérifier les fichiers IBDATA1), la défaillance du chargement du plug-in (vérification du journal des erreurs). Lors de la résolution de problèmes, vous devez les analyser en fonction du journal d'erreur, trouver la cause profonde du problème et développer l'habitude de sauvegarder régulièrement les données pour prévenir et résoudre des problèmes.

MySQL peut-il fonctionner sur Android MySQL peut-il fonctionner sur Android Apr 08, 2025 pm 05:03 PM

MySQL ne peut pas fonctionner directement sur Android, mais il peut être implémenté indirectement en utilisant les méthodes suivantes: à l'aide de la base de données légère SQLite, qui est construite sur le système Android, ne nécessite pas de serveur distinct et a une petite utilisation des ressources, qui est très adaptée aux applications de périphériques mobiles. Connectez-vous à distance au serveur MySQL et connectez-vous à la base de données MySQL sur le serveur distant via le réseau pour la lecture et l'écriture de données, mais il existe des inconvénients tels que des dépendances de réseau solides, des problèmes de sécurité et des coûts de serveur.

Solutions aux erreurs rapportées par MySQL sur une version système spécifique Solutions aux erreurs rapportées par MySQL sur une version système spécifique Apr 08, 2025 am 11:54 AM

La solution à l'erreur d'installation de MySQL est: 1. Vérifiez soigneusement l'environnement système pour vous assurer que les exigences de la bibliothèque de dépendance MySQL sont satisfaites. Différents systèmes d'exploitation et exigences de version sont différents; 2. Lisez soigneusement le message d'erreur et prenez des mesures correspondantes en fonction des invites (telles que les fichiers de bibliothèque manquants ou les autorisations insuffisantes), telles que l'installation de dépendances ou l'utilisation de commandes sudo; 3. Si nécessaire, essayez d'installer le code source et vérifiez soigneusement le journal de compilation, mais cela nécessite une certaine quantité de connaissances et d'expérience Linux. La clé pour finalement résoudre le problème est de vérifier soigneusement l'environnement du système et les informations d'erreur et de se référer aux documents officiels.

MySQL ne peut pas être installé après le téléchargement MySQL ne peut pas être installé après le téléchargement Apr 08, 2025 am 11:24 AM

Les principales raisons de la défaillance de l'installation de MySQL sont les suivantes: 1. Problèmes d'autorisation, vous devez s'exécuter en tant qu'administrateur ou utiliser la commande sudo; 2. Des dépendances sont manquantes et vous devez installer des packages de développement pertinents; 3. Conflits du port, vous devez fermer le programme qui occupe le port 3306 ou modifier le fichier de configuration; 4. Le package d'installation est corrompu, vous devez télécharger et vérifier l'intégrité; 5. La variable d'environnement est mal configurée et les variables d'environnement doivent être correctement configurées en fonction du système d'exploitation. Résolvez ces problèmes et vérifiez soigneusement chaque étape pour installer avec succès MySQL.

Impossible d'accéder à MySQL depuis Terminal Impossible d'accéder à MySQL depuis Terminal Apr 08, 2025 pm 04:57 PM

Impossible d'accéder à MySQL à partir du terminal peut être dû à: le service MySQL n'est pas en cours d'exécution; Erreur de commande de connexion; autorisations insuffisantes; Connexion de blocs de pare-feu; Erreur de fichier de configuration MySQL.

See all articles