Speicherverwaltung mit struct epoll_event

Lesezeit: 3 Minuten

Ich entwickle einen Server in C mit dem epoll-Bibliothek und ich habe eine Frage, wie der Speicher gehandhabt wird struct epoll_event. Ich habe in einigen Online-Beispielen bemerkt, dass beim Erstellen epoll_ctl Anrufe, die events Argument wird auf dem Stapel zugewiesen und dann wird der Zeiger wie folgt übergeben:

struct epoll_event ev;
ev.events = EPOLLIN;
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);

Jetzt wissen wir alle, was passiert ev wenn die Funktion zurückkehrt. Meine Frage ist: Erstellt die Epoll-Bibliothek intern Kopien dieser Werte oder verlässt sie sich auf die Struktur, die Sie übergeben haben, um dem Heap zugewiesen zu werden? Wird das obige Beispiel meine Reaktorimplementierung vollständig zerstören? Wenn ja, was ist der beste Weg, um den Überblick über meinen zugewiesenen Heap zu behalten? epoll_event Strukturen?

Vielen Dank für Ihre Zeit.

  • Wenn “wir alle wissen, was passiert”, warum fragst du dann?

    – Kerrek SB

    19. Oktober 2012 um 21:03 Uhr

  • Wenn ich sage “Wir alle wissen, was passiert”, meine ich, dass der vom Stapel zugewiesene Speicher freigegeben wird, wenn die Funktion zurückkehrt.

    – Blake Beaupain

    19. Oktober 2012 um 21:07 Uhr

Alles ist gut. Das epoll_ctl Die Funktion ist ein einfacher Wrapper um einen Systemaufruf, der vollständig abgeschlossen ist, wenn die Funktion zurückkehrt. Es werden keine weiteren Daten aus dem Userspace benötigt. Die Struktur ist einfach eine Möglichkeit, die Argumente zu verpacken.

  • Ich wünschte, diese Informationen wären in der Manpage und erforderten keinen Roundtrip zu SO.

    – Domson

    16. Januar 2020 um 17:38 Uhr

Es ist völlig in Ordnung, Ihre epoll_event-Struktur sofort wegzuwerfen oder wiederzuverwenden.

Der Kernel kopiert die Parameter aus der epoll_event-Struktur.

Dies ist genau dasselbe, als ob Sie ein ioctl verwenden, das eine Struktur als Parameter verwendet, oder eine Socket-Operation (z. B. bind), die eine Struktur sockaddr_in akzeptiert.

Der Kernel nimmt, was er braucht, und Sie können ihn sofort freigeben.

Das Einzige, worum Sie sich kümmern müssen, sind die „Nutzungsdaten“, die nur für Sie relevant sind. Der Kernel wird es speichern, aber Sie müssen wissen, was es bedeutet, wenn Sie ein Ereignis erhalten.

  • Vielen Dank. Hochgestimmt. Ich werde die Antwort von Kerrek SB jedoch als richtig markieren, da er ungefähr eine Minute vor Ihnen geantwortet hat.

    – Blake Beaupain

    19. Oktober 2012 um 21:06 Uhr

epoll ist eine Reihe von Systemaufrufen, keine Bibliothek. Wenn Sie die anrufen epoll syscalls geben Sie den Kernel ein, und der Kernel vertraut im Allgemeinen nicht darauf, dass diese Benutzermoduspuffer unbedingt gültig sind oder bleiben, sondern kopiert sie in den Kernelspeicher über copy_from_user usw. Also ja, Sie können Strukturen auf dem Stack einrichten, ihre Adressen an den Systemaufruf übergeben und sie dann nach der Rückkehr verwerfen.

Wie alle sagen, die Erinnerung an die struct epoll_event * Parameterpunkte können nach epoll_ctl() freigegeben oder wiederverwendet werden.

Im linux/v5.8/source/fs/eventpoll.c#L2288sehen wir, dass der Kernel eine Kopie der Struktur epoll_event erstellt, die bestätigt, was wir glauben.

SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
        struct epoll_event __user *, event)
{
    struct epoll_event epds;

    if (ep_op_has_event(op) &&
        copy_from_user(&epds, event, sizeof(struct epoll_event)))
        return -EFAULT;

    return do_epoll_ctl(epfd, op, fd, &epds, false);
}

1213890cookie-checkSpeicherverwaltung mit struct epoll_event

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy