Vektor-E / A - Vectored I/O

Beim Rechnen ist Vektor-E / A , auch als Streu- / Sammel-E / A bekannt , eine Eingabe- und Ausgabemethode, mit der ein einzelner Prozeduraufruf nacheinander Daten aus mehreren Puffern liest und in einen einzelnen Datenstrom schreibt oder Daten aus diesen liest und ein Datenstrom schreibt sie in mehrere Puffer, wie in einem definierten Vektor von Puffern. Streuung / Sammeln bezieht sich auf den Prozess des Sammelns oder Streuens von Daten aus dem gegebenen Satz von Puffern. Vektor-E / A können synchron oder asynchron arbeiten. Die Hauptgründe für die Verwendung von Vektor-E / A sind Effizienz und Komfort.

Vektor-E / A hat mehrere Verwendungsmöglichkeiten:

  • Atomizität : Wenn die bestimmte vektorisierte E / A-Implementierung Atomizität unterstützt, kann ein Prozess in eine Reihe von Puffern in oder aus einer Datei schreiben oder aus dieser lesen, ohne dass das Risiko besteht, dass ein anderer Thread oder Prozess zwischen dem ersten Prozess E / A für dieselbe Datei ausführt 'liest oder schreibt, wodurch die Datei beschädigt oder die Integrität der Eingabe beeinträchtigt wird
  • Verketten der Ausgabe: Eine Anwendung, die nicht sequentiell platzierte Daten in den Speicher schreiben möchte, kann dies in einer vektorisierten E / A-Operation tun. Das Schreiben eines Headers mit fester Größe und der zugehörigen Nutzdaten, die nicht sequentiell im Speicher abgelegt werden, kann beispielsweise durch eine einzelne vektorisierte E / A-Operation erfolgen, ohne zuvor den Header und die Nutzdaten in einen anderen Puffer zu verketten
  • Effizienz: Ein vektorisierter E / A-Lese- oder Schreibvorgang kann viele normale Lese- oder Schreibvorgänge ersetzen und so den mit Systemaufrufen verbundenen Overhead einsparen
  • Aufteilung der Eingabe: Beim Lesen von Daten, die in einem Format gespeichert sind, das einen Header mit fester Größe definiert, kann ein Puffervektor verwendet werden, in dem der erste Puffer die Größe dieses Headers hat. und der zweite Puffer enthält die dem Header zugeordneten Daten

Normungsgremien dokumentieren die anwendbaren Funktionen readv und writev in POSIX 1003.1-2001 und der Single UNIX Specification Version 2. Die Windows-API verfügt über analoge Funktionen ReadFileScatter und WriteFileGather ; Im Gegensatz zu den POSIX-Funktionen erfordern sie jedoch die Ausrichtung jedes Puffers auf einer Speicherseite . Winsock bietet getrennte WSASend und WSARecv Funktionen ohne diese Anforderung.

Während das direkte Arbeiten mit einem Puffervektor erheblich schwieriger sein kann als das Arbeiten mit einem einzelnen Puffer, kann die Verwendung übergeordneter APIs für ein effizientes Arbeiten die Schwierigkeiten verringern.

Beispiele

Das folgende Beispiel druckt "Hallo, Wikipedia-Community!" auf die Standardausgabe . Jedes Wort wird in einem einzigen Puffer gespeichert und mit nur einem Aufruf von writev() werden alle Puffer auf die Standardausgabe gedruckt.

#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <sys/uio.h>

int main(int argc, char *argv[])
{
	const char buf1[] = "Hello, ";
	const char buf2[] = "Wikipedia ";
	const char buf3[] = "Community!\n";

	struct iovec bufs[] = {
		{ .iov_base = (void *) buf1, .iov_len = sizeof(buf1) - 1 },
		{ .iov_base = (void *) buf2, .iov_len = sizeof(buf2) - 1 },
		{ .iov_base = (void *) buf3, .iov_len = sizeof(buf3) - 1 },
	};

	if (-1 == writev(STDOUT_FILENO, bufs, sizeof(bufs) / sizeof(*bufs)))
	{
		perror("writev()");
		exit(EXIT_FAILURE);
	}

	return EXIT_SUCCESS;
}

Verweise