Ich arbeite an der Implementierung eines Datenbankservers in C, der Anfragen von mehreren Clients verarbeiten wird. Um dies zu tun, verwende ich fork (), um Verbindungen für einzelne Clients zu handhaben.
Der Server speichert Daten im Heap, der aus einem Wurzelzeiger auf Hashtabellen von dynamisch zugewiesenen Datensätzen besteht. Die Datensätze sind Strukturen, die Zeiger auf verschiedene Datentypen haben. Ich möchte, dass die Prozesse in der Lage sind, diese Daten zu teilen, so dass, wenn ein Client eine Änderung am Heap durchführt, die Änderungen für die anderen Clients sichtbar sind.
Ich habe gelernt, dass fork () COW (Copy On Write) verwendet und mein Verständnis ist das Es kopiert den Heap- (und Stack-) Speicher des übergeordneten Prozesses, wenn das Kind versucht, die Daten im Speicher zu ändern.
Ich habe herausgefunden, dass ich die SHM-Bibliothek verwenden kann, um Speicher freizugeben.
- Wäre es ausreichend, den Stammzeiger der Datenbank freizugeben, oder muss ich den gesamten zugewiesenen Speicher als gemeinsam nutzen?
- Wenn ein Kind Speicher reserviert, können Eltern / andere Kinder darauf zugreifen?
- Auch wenn ein Kind Speicher zuweist und später getötet wird, bleibt der zugewiesene Speicher immer noch auf dem Heap?
Zum Beispiel wäre der folgende Code eine gültige Möglichkeit, den Heap-Speicher freizugeben (in shared_string)? Wenn ein Kind ähnlichen Code verwenden würde (d. H. Beginnend mit // start), könnten andere Kinder lesen / schreiben, während das Kind läuft und nachdem es tot ist?
%Vor% Erstens ist fork
völlig ungeeignet für das, was Sie erreichen möchten. Selbst wenn Sie es schaffen können, ist es ein schrecklicher Hack. Im Allgemeinen funktioniert fork
sowieso nur für sehr simple Programme, und ich würde so weit gehen zu sagen, dass fork
niemals verwendet werden sollte, außer schnell gefolgt von exec
, aber das ist abgesehen von dem Punkt hier. Sie sollten wirklich Threads verwenden.
Damit ist die einzige Möglichkeit, nach dem fork
einen Speicher zu haben, der nach mmap
geteilt wird, und wo die gleichen Zeiger in beiden gültig sind, ist shmat
(oder MAP_SHARED
, aber das ist eine Menge fuglier) eine Datei oder eine anonyme Karte mit fork
vor fork
. Sie können nach fork
keinen neuen Shared Memory wie diesen erstellen, da es keine Garantie gibt, dass er in beiden Adressbereichen in demselben Adressbereich abgebildet wird.
Verwenden Sie einfach nicht %code% . Es ist nicht das richtige Werkzeug für den Job.
Tut mir leid, dass ich einen Monat später geantwortet habe, aber ich glaube nicht, dass die vorhandenen Antworten das gaben, wonach das OP verlangte.
Ich denke, Sie wollen grundsätzlich tun, was Redis (und wahrscheinlich andere) tun. Sie beschreiben es in Ссылка (suchen Sie nach "copy-on-write").
Der Hauptvorteil der Verwendung dieser Methode ist die Vermeidung von Blockierung, die ein Schmerz sein kann, um richtig zu werden.
Soweit ich es verstehe, ist die Idee, COW zu verwenden,:
Dinge, auf die Sie achten sollten:
Vielleicht möchten Sie gander auch beim Code erneut verwenden .
Wäre es ausreichend, den Wurzelzeiger der Datenbank zu teilen, oder muss ich den gesamten zugewiesenen Speicher als gemeinsam nutzen?
Nein, weil jeder Prozess seinen eigenen privaten Speicherbereich hat. Copy-on-Write ist eine Kernel-Space-Optimierung, die für den Benutzerbereich transparent ist.
Wie andere bereits gesagt haben, sind SHM- oder MMAP-Dateien die einzige Möglichkeit, Speicher zwischen einzelnen Prozessen gemeinsam zu nutzen.
Viele populäre HTTP-Server verwenden fork (), um mehrere Prozessoren zu nutzen, Nginx ist einer davon.
Threading bringt eine ganze Reihe von Kopfschmerzen mit sich, die ich persönlich vermeiden möchte, es sei denn, es ist absolut notwendig. Ihr Programm wird niemals von Abstürzen durch Multithreading-Fehler frei sein (meine Erfahrung mit Threading-Code anderer Leute).
MitMultiprocessing können Sie alle Prozessoren auf Ihrer Maschine verwenden, ohne implizit Speicher zwischen den Ausführungs-Threads zu teilen, indem Sie standardmäßig alle typischen, endlosen Multithreading-Fehler vermeiden.
Ich mag es nachts zu schlafen, ohne diese 2am Anrufe zu bekommen, weil ich weiß, dass meine Webfrontend Server mit hohem Durchsatz nicht auf mich stürzen werden, weil ich an diesem Tag keine von Dutzenden Multithreading-Fallen gesehen habe.
Es gibt viele Fälle, in denen Shared Memory schmerzfrei ist, z. B. wenn die Daten im Shared Memory nur gelesen werden können. Sie müssen sich nicht um Schlösser usw. kümmern.
Wenn Sie fork
haben müssen, scheint der gemeinsame Speicher die einzige Wahl zu sein.
Eigentlich finde ich in deiner Szene den Thread besser geeignet.
Wenn Sie nicht Multi-Threading sein wollen. Hier ist eine andere Wahl, Sie können nur ein Prozess & amp; Ein-Thread-Modus, wie redis
In diesem Modus brauchen Sie sich nicht um etwas wie lock
zu sorgen, und wenn Sie skalieren möchten, erstellen Sie einfach eine Routenrichtlinie als Route mit dem Hash-Wert von key
Tags und Links c c++ shared-memory fork heap