Vorwort

Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com

Rust hat maßgeblich dazu beigetragen, die Systemprogrammierung zugänglicher zu machen, aber Low-Level-Concurrency-Themen wie Atomic und Memory Ordering werden immer noch als etwas mystische Themen angesehen, die am besten einer kleinen Gruppe von Experten vorbehalten sind.

Während meiner Arbeit an Rust-basierten Echtzeitsteuerungssystemen und der Rust-Standardbibliothek in den letzten Jahren habe ich festgestellt, dass viele der verfügbaren Ressourcen zu Atomics und verwandten Themen nur einen kleinen Teil der Informationen abdecken, nach denen ich gesucht habe. Viele Ressourcen konzentrieren sich ausschließlich auf C und C++, was es schwierig machen kann, eine Verbindung zu Rusts Konzept der (Speicher- und Thread-)Sicherheit und dem Typensystem herzustellen. Die Ressourcen, die die Details der abstrakten Theorie abdecken, wie z. B. das Speichermodell von C++, erklären oft nur vage, wie es sich auf die tatsächliche Hardware bezieht, wenn überhaupt. Es gibt viele Ressourcen, die jedes Detail der tatsächlichen Hardware abdecken, wie z. B. Prozessoranweisungen und Cache-Kohärenz, aber um ein ganzheitliches Verständnis zu erlangen, muss man oft Bits und Stücke von Informationen aus vielen verschiedenen Orten sammeln.

Dieses Buch ist ein Versuch, die relevanten Informationen an einem Ort zu bündeln und sie miteinander zu verknüpfen. Es bietet alles, was du brauchst, um deine eigenen korrekten, sicheren und ergonomischen Gleichzeitigkeits-Primitive zu entwickeln und gleichzeitig genug über die zugrundeliegende Hardware und die Rolle des Betriebssystems zu wissen, um Design-Entscheidungen und grundlegende Kompromisse bei der Optimierung treffen zu können.

Für wen dieses Buch ist

Dieses Buch richtet sich in erster Linie an Rust-Entwickler, die mehr über Low-Level-Gleichzeitigkeit erfahren wollen, aber auch an diejenigen, die mit Rust noch nicht so vertraut sind, aber gerne wissen möchten, wie Low-Level-Gleichzeitigkeit aus der Rust-Perspektive aussieht.

Es wird davon ausgegangen, dass du die Grundlagen von Rust kennst, einen aktuellen Rust-Compiler installiert hast und weißt, wie man Rust-Code mit cargo kompiliert und ausführt. Rust-Konzepte, die für die Gleichzeitigkeit wichtig sind, werden kurz erklärt, wenn sie relevant sind, sodass keine Vorkenntnisse über Rust-Gleichzeitigkeit erforderlich sind.

Überblick über die Kapitel

Dieses Buch besteht aus zehn Kapiteln. Hier erfährst du, was du von jedem Kapitel erwarten kannst und worauf du dich freuen kannst:

Kapitel 1 - Grundlagen der Rust-Gleichzeitigkeit

In diesem Kapitel werden alle Werkzeuge und Konzepte vorgestellt, die wir für die grundlegende Gleichzeitigkeit in Rust benötigen, z. B. Threads, Mutexe, Thread-Sicherheit, gemeinsame und exklusive Referenzen, interne Veränderbarkeit usw., die für den Rest des Buches grundlegend sind.

Für erfahrene Rust-Programmierer, die mit diesen Konzepten vertraut sind, kann dieses Kapitel als schnelle Auffrischung dienen. Für diejenigen, die diese Konzepte aus anderen Sprachen kennen, aber noch nicht sehr vertraut mit Rust sind, wird dieses Kapitel schnell alle Rust-spezifischen Kenntnisse vermitteln, die du für den Rest des Buches brauchst.

Kapitel 2 - Atomkraft

Im zweiten Kapitel lernen wir die atomaren Typen von Rust und all ihre Operationen kennen. Wir beginnen mit einfachen Lade- und Speicheroperationen und arbeiten uns bis zu fortgeschrittenen Vergleichs- und Austauschschleifen vor, wobei wir jedes neue Konzept anhand von mehreren realen Anwendungsfällen erkunden.

Die Speicheranordnung ist zwar für jede atomare Operation relevant, aber dieses Thema wird im nächsten Kapitel behandelt. Dieses Kapitel behandelt nur Situationen, in denen eine entspannte Speicheranordnung ausreicht, was häufiger der Fall ist, als man vielleicht erwartet.

Kapitel 3 - Speicheranordnung

Nachdem du die verschiedenen atomaren Operationen und ihre Verwendung kennengelernt hast, führt das dritte Kapitel in das komplizierteste Thema des Buches ein: dieSpeicherordnung.

Wir werden uns ansehen, wie das Speichermodell funktioniert, was Vorgänge sind und wie man sie herstellt, was die verschiedenen Speicheranordnungen bedeuten und warum die sequentiell konsistente Anordnung vielleicht nicht die Antwort auf alles ist.

Kapitel 4 - Unser eigenes Spin Lock bauen

Nachdem wir die Theorie kennengelernt haben, setzen wir sie in den nächsten drei Kapiteln in die Praxis um, indem wir unsere eigenen Versionen verschiedener gängiger Gleichzeitigkeits-Primitive bauen. Das erste dieser Kapitel ist ein kurzes Kapitel, in dem wir ein Spin Lock implementieren.

Wir fangen mit einer sehr minimalen Version an, um dieFreigabe- und Erfassungsreihenfolge in der Praxis zu üben, und dann werden wir das Sicherheitskonzept von Rust untersuchen, um es in einen ergonomischen und schwer zu missbrauchenden Rust-Datentyp zu verwandeln.

Kapitel 5 - Unsere eigenen Kanäle aufbauen

In Kapitel 5 werden wir von Grund auf eine Handvoll Variationen eines One-Shot-Channels implementieren, ein Primitiv, mit dem man Daten von einem Thread zu einem anderen senden kann.

Beginnend mit einer sehr minimalen, aber vollständig unsafe Version, arbeiten wir uns durch verschiedene Möglichkeiten, eine sichere Schnittstelle zu entwerfen, während wir Design-Entscheidungen und ihre Konsequenzen berücksichtigen.

Kapitel 6 - Unseren eigenen "Bogen" bauen

Im sechsten Kapitel nehmen wir uns ein anspruchsvolleres Rätsel vor: Wir werden unsere eigene Version der atomaren Referenzzählung von Grund auf implementieren.

Nachdem wir die Unterstützung für schwache Zeiger hinzugefügt und die Leistung optimiert haben, wird unsere endgültige Version praktisch identisch mit dem Standardtyp std::sync::Arc von Rust sein.

Kapitel 7 - Verständnis des Prozessors

Im siebten Kapitel tauchen wir tief in alle Low-Level-Details ein. Wir erkunden, was auf der Prozessorebene passiert, wie die Assembler-Befehle hinter den atomaren Operationen auf den beiden gängigsten Prozessorarchitekturen aussehen, was Caching ist und wie es sich auf die Leistung unseres Codes auswirkt, und wir finden heraus, was vom Speichermodell auf der Hardware-Ebene übrig bleibt.

Kapitel 8 - Primitive Betriebssysteme

In Kapitel 8 erkennen wir an, dass es Dinge gibt, die wir ohne die Hilfe des Betriebssystemkerns nicht tun können, und lernen, welche Funktionen unter Linux, macOS und Windows verfügbar sind.

Wir besprechen die Gleichzeitigkeitsprimitive, die über pthreads auf POSIX-Systemen verfügbar sind, finden heraus, was wir mit der Windows-API tun können, und lernen, was der Linux futex syscall tut.

Kapitel 9 - Unsere eigenen Schlösser bauen

Mit dem, was wir in den vorherigen Kapiteln gelernt haben, werden wir in Kapitel 9 mehrere Implementierungen einer Mutex, einer Bedingungsvariablen und einerLeser-Schreiber-Sperre von Grund auf neu erstellen.

Wir beginnen mit einer minimalen, aber vollständigen Version und versuchen, diese auf verschiedene Weise zu optimieren. Anhand einiger einfacher Benchmark-Tests werden wir herausfinden, dass unsere Optimierungsversuche nicht immer zu einer Leistungssteigerung führen, während wir verschiedene Kompromisse beim Design diskutieren.

Kapitel 10 - Ideen und Inspiration

Das letzte Kapitel sorgt dafür, dass du nach Beendigung des Buches nicht ins Leere fällst, sondern mit Ideen und Inspirationen für Dinge zurückbleibst, die du mit deinem neuen Wissen und deinen Fähigkeiten bauen und erforschen kannst, um vielleicht eine aufregende Reise in die Tiefen der Nebenläufigkeit anzutreten.

Code Beispiele

Der gesamte Code in diesem Buch wurde für Rust 1.66.0 geschrieben und getestet, das am 15. Dezember 2022 veröffentlicht wurde. Frühere Versionen enthalten nicht alle Funktionen, die in diesem Buch verwendet werden. Spätere Versionen sollten jedoch problemlos funktionieren.

Aus Gründen der Kürze enthalten die Codebeispiele keine use Anweisungen, es sei denn, ein neues Element aus der Standardbibliothek wird zum ersten Mal eingeführt. Das folgende Vorspiel kann verwendet werden, um alles zu importieren, was zum Kompilieren der Codebeispiele in diesem Buch notwendig ist:

#[allow(unused)]
use std::{
    cell::{Cell, RefCell, UnsafeCell},
    collections::VecDeque,
    marker::PhantomData,
    mem::{ManuallyDrop, MaybeUninit},
    ops::{Deref, DerefMut},
    ptr::NonNull,
    rc::Rc,
    sync::{*, atomic::{*, Ordering::*}},
    thread::{self, Thread},
};

Zusätzliches Material, einschließlich vollständiger Versionen aller Code-Beispiele, ist unter https://marabos.nl/atomics/ verfügbar .

Du kannst den gesamten Beispielcode, der mit diesem Buch angeboten wird, für jeden Zweck verwenden.

Eine Namensnennung ist erwünscht, aber nicht erforderlich. Eine Quellenangabe umfasst normalerweise den Titel, den Autor, den Verlag und die ISBN. Zum Beispiel: "Rust Atomics and Locks von Mara Bos (O'Reilly). Copyright 2023 Mara Bos, 978-1-098-11944-7."

In diesem Buch verwendete Konventionen

In diesem Buch werden die folgenden typografischen Konventionen verwendet:

Kursiv

Wird für neue Begriffe, URLs und Hervorhebungen verwendet.

Constant width

Wird für Programmlistings sowie innerhalb von Absätzen verwendet, um auf Programmelemente wie Variablen- oder Funktionsnamen, Datentypen, Anweisungen und Schlüsselwörter hinzuweisen.

Tipp

Dieses Element steht für einen Tipp oder eine Anregung.

Hinweis

Dieses Element steht für einen allgemeinen Hinweis.

Warnung

Dieses Element weist auf eine Warnung oder einen Warnhinweis hin.

Kontaktinformationen

O'Reilly hat eine Webseite für dieses Buch, auf der Errata, Beispiele und zusätzliche Informationen aufgeführt sind. Es ist unter https://oreil.ly/rust-atomics-and-locks erhältlich .

Schicke eine E-Mail an , um Kommentare oder technische Fragen zu diesem Buch zu stellen. Wenn du Inhalte aus diesem Buch wiederverwenden möchtest und du der Meinung bist, dass deine Wiederverwendung nicht unter die faire Nutzung oder die in diesem Vorwort gegebene Erlaubnis fällt, wende dich bitte an O'Reilly unter

Neuigkeiten und Informationen über O'Reilly findest du unter https://oreilly.com.

Folge O'Reilly auf Twitter: https://twitter.com/oreillymedia.

Folge dem Autor auf Twitter: https://twitter.com/m_ou_se.

Danksagungen

Ich möchte mich bei allen bedanken, die an der Entstehung dieses Buches beteiligt waren. Viele Menschen haben mich unterstützt und mir nützliche Anregungen gegeben, die unglaublich hilfreich waren. Insbesondere möchte ich Amanieu d'Antras, Aria Beingessner, Paul McKenney, Carol Nichols und Miguel Raz Guzmán Macedo für ihr wertvolles und durchdachtes Feedback zu den ersten Entwürfen danken. Außerdem möchte ich mich bei allen Mitarbeitern von O'Reilly und insbesondere bei meinen Redakteuren Shira Evans und Zan McQuade für ihre unerschöpfliche Begeisterung und Unterstützung bedanken.

Get Rust Atomics und Schlösser now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.