Опубликовано

Новинка: “Экскурс в неопределенное поведение C++”

Экскурс в неопределенное поведение C++

Книга представляет собой обширный справочник  типичных, а также очень редко встречающихся ошибок, характерных для программ на C++, Rust и других  языках для низкоуровневого и системного программирования, в частности на ассемблере. Все рассмотренные проблемы так или иначе связаны с неопределенным, неуточненным и определяемым реализацией поведением языковых конструкций. Наибольшее внимание уделено неопределенному поведению, возможным признакам его присутствия в программах и методам поиска, диагностики и устранения такого поведения.

Для специалистов по C++ и другим языкам для системного и низкоуровневого программирования

Вы изучили C++ за 21 день и уже готовы использовать его во всех своих проектах? Погодите, есть кое-что еще!

За последние годы особенно остро поднят вопрос безопасности при разработке программного обеспечения: операционных систем, драйверов, веб-серверов и облачных платформ. C++ считается одним из самых небезопасных языков программирования, который широко используются в реальных программах. С 2023 года звучат призывы избегать языка C++ из-за того, что в нём не гарантирована безопасность памяти: 70% всех уязвимостей в программном обеспечении так или иначе оказывались связаны с работой с памятью.

В этой книге приводится множество разнообразных примеров из реальной практики, демонстрирующих, как даже самый безобидный на первый взгляд код на C++ или C может скрывать в себе невероятные ошибки. Всё это из-за множества явных и неявных случаев неопределенного поведения, и лишь некоторые такие случаи описаны в стандартах этих языков. На страницах книги вы увидите, как истинные условия могут стать ложными, а недостижимый код начать выполняться, как код, работающий на вашей машине, перестанет работать у вашего коллеги, и как, добавив журналирование, можно «починить» код на время. С неопределенным поведением возможно всё!

  • Десятки историй о неоднозначных и сомнительных решениях в дизайне языка С++, приводящих к многим часам отладки в реальных проектах
  • Самые неожиданные ошибки и как они проявляются
  • Советы как избежать встречи с одним из самых загадочных “зверей” в разработке на C++ и других языках для системного и низкоуровневого программирования — неопределенным поведением

Книгу “Экскурс в неопределенное поведение C++” можно купить в нашем интенет-магазине.

Опубликовано

Новинка: “Rust. Профессиональное программирование”

Rust. Профессиональное программирование

Книга служит введением в продвинутые темы, необходимые для реализации полнофункциональных проектов на языке Rust. Rust рассматривается как сравнительно новый, но мощный и зрелый язык для серверного программирования. Рассмотрены паттерны проектирования, характерные для Rust, роль Rust в современном низкоуровневом программировании, приемы асинхронных взаимодействий и управление памятью. Проиллюстрированы способы создания HTTP REST API на Rust, интеграция кода Rust с кодом на других языках, типичные идиомы и структуры данных, применяемые при профессиональной работе с Rust.

Для Rust-разработчиков и специалистов по системному программированию

Книга ориентирована на читателей, имеющих базовые представления о Rust

Язык Rust успел прославиться своей высокой производительностью, надёжностью и безопасностью. Но не так просто овладеть им в совершенстве, чтобы все эти достоинства раскрылись в полной мере. Эта книга поможет вам быстро стартовать в изучении сложных тем, уверенно приступить к работе с низкоуровневыми системами, веб-приложениями, заниматься асинхронным программированием, оптимизацией, писать конкурентный код.
С этой книгой вы сможете работать более продуктивно. Она насыщена примерами и, опираясь на уже имеющиеся у вас знания, познакомит вас со специфичными для Rust паттернами проектирования, приёмами асинхронного программирования, а также поможет интегрировать Rust с другими языками. Также в ней рассказано о замечательных инструментах для тестирования, анализа кода, управления жизненным циклом приложения на Rust. Всё самое нужное — под одной обложкой!

В этой книге:

  • Структуры данных Rust
  • Управление памятью
  • Создание эффективных API
  • Инструментарий Rust, средства для тестирования и многое другое

 

Каждый Rust-разработчик что-то найдёт для себя в этой книге. Просто кладезь советов.
Тим Макнамара, основатель компании Accelerant.dev, автор книги «Rust в действии»

Та самая книга, которая поможет стать Rust-профессионалом.
Хайме Лопес, Институт Гуттманна, Барселона

Практичная, удобная и понятная книга.
Сатедж Кумар Саху, компания «Боинг»

Для всех амбициозных растофилов.
Симон Чоке, компания German Edge Cloud

 

Книгу “Rust. Профессиональное программирование“.

Краткое оглавление…………………………………………………………………………………. 5

Предисловие…………………………………………………………………………………………… 13

Благодарности……………………………………………………………………………………….. 15

Об этой книге………………………………………………………………………………………… 17

В чем особенность этой книги?………………………………………………………………………………………………… 17

Для кого она предназначена?…………………………………………………………………………………………………… 17

Структура книги………………………………………………………………………………………………………………………… 18

О программном коде………………………………………………………………………………………………………………….. 19

Дискуссионный форум liveBook……………………………………………………………………………………………….. 20

Об авторе……………………………………………………………………………………………….. 21

Об иллюстрации на обложке………………………………………………………………….. 23

Глава 1. Почувствуйте Rust!…………………………………………………………………… 25

1.1. Так чем же примечателен Rust?…………………………………………………………………………………………. 26

1.2. В чем же уникальность Rust?…………………………………………………………………………………………….. 28

1.2.1. Rust безопасен………………………………………………………………………………………………………….. 28

1.2.2. Rust современен………………………………………………………………………………………………………… 30

1.2.3. У Rust абсолютно открытый исходный код…………………………………………………………… 30

1.2.4. Сравнение Rust с другими популярными языками………………………………………………… 31

1.3. В каких случаях стоит воспользоваться языком Rust?……………………………………………………. 32

1.4. Требуемые инструменты……………………………………………………………………………………………………. 33

Резюме…………………………………………………………………………………………………………………………………………. 34

Часть I. Работа с Rust на профессиональном уровне…….. 35

Глава 2. Управление проектами с помощью Cargo………………………………… 37

2.1. Ознакомительный тур по Cargo…………………………………………………………………………………………. 38

2.1.1. Основное применение………………………………………………………………………………………………. 38

2.1.2. Создание нового приложения или библиотеки……………………………………………………… 39

2.1.3. Компиляция, запуск и тестирование………………………………………………………………………. 41

2.1.4. Переключения между наборами инструментов…………………………………………………….. 42

2.2. Управление зависимостями……………………………………………………………………………………………….. 43

2.3. Фича-флаги………………………………………………………………………………………………………………………….. 46

2.4. Корректировка зависимостей…………………………………………………………………………………………….. 49

2.4.1. Косвенные зависимости…………………………………………………………………………………………… 51

2.4.2. Лучшие методы корректировки зависимостей………………………………………………………. 51

2.5. Публикация крейтов……………………………………………………………………………………………………………. 52

2.5.1. CI/CD-интеграция…………………………………………………………………………………………………….. 52

2.6. Ссылки на библиотеки С……………………………………………………………………………………………………. 56

2.7. Бинарный дистрибутив………………………………………………………………………………………………………. 59

2.7.1. Кросс-компиляция……………………………………………………………………………………………………. 59

2.7.2. Создание статически связанных бинарных файлов……………………………………………… 60

2.8. Документирование Rust-проектов…………………………………………………………………………………….. 62

2.8.1. Примеры кода в документации……………………………………………………………………………….. 65

2.9. Модули………………………………………………………………………………………………………………………………… 66

2.10. Рабочие пространства……………………………………………………………………………………………………… 69

2.11. Пользовательские сценарии сборки………………………………………………………………………………… 71

2.12. Проекты Rust во встраиваемых средах…………………………………………………………………………… 73

Резюме…………………………………………………………………………………………………………………………………………. 75

Глава 3. Инструменты Rust……………………………………………………………………. 77

3.1. Общий обзор инструментария Rust…………………………………………………………………………………… 78

3.2. IDE-интеграция Rust: инструмент rust-analyzer……………………………………………………………….. 79

3.2.1. Установка rust-analyzer……………………………………………………………………………………………. 79

3.2.2. Магические завершения…………………………………………………………………………………………… 80

3.3. Поддержка аккуратности кода: инструмент rustfmt……………………………………………………….. 83

3.3.1. Установка rustfmt…………………………………………………………………………………………………….. 83

3.3.2. Конфигурирование rustfmt………………………………………………………………………………………. 84

3.4. Повышение качества кода: инструмент Clippy………………………………………………………………… 85

3.4.1. Установка Clippy………………………………………………………………………………………………………. 86

3.4.2. Clippy-линты……………………………………………………………………………………………………………… 86

3.4.3. Конфигурирование Clippy……………………………………………………………………………………….. 88

3.4.4. Автоматическое применение предложений Clippy……………………………………………….. 89

3.4.5. Использование Clippy в CI/CD………………………………………………………………………………… 89

3.5. Сокращение времени компиляции: инструмент sccache…………………………………………………. 90

3.5.1. Установка sccache……………………………………………………………………………………………………. 91

3.5.2. Конфигурирование sccache……………………………………………………………………………………… 91

3.6. Интеграция Rust с IDE-средами, включая Visual Studio Code…………………………………………. 91

3.7. Использование наборов инструментов: стабильные и ночные версии………………………….. 92

3.7.1. Функции, доступные только в ночной версии……………………………………………………….. 93

3.7.2. Использование nightly-функций в публикуемых крейтах……………………………………… 94

3.8. Дополнительные инструменты: cargo-update, cargo-expand, cargo-fuzz, cargo-watch, cargo-tree  94

3.8.1. Поддержание пакетов в актуальном состоянии: инструмент cargo-update……….. 95

3.8.2. Отладка макросов: инструмент cargo-expand……………………………………………………….. 95

3.8.3. Тестирование с применением libFuzzer…………………………………………………………………… 96

3.8.4. Периодический запуск Cargo-команд: инструмент cargo-watch………………………….. 97

3.8.5. Проверка зависимостей: инструмент cargo-tree……………………………………………………. 97

Резюме…………………………………………………………………………………………………………………………………………. 99

Часть II. Основные данные………………………………………………………. 101

Глава 4. Структуры данных…………………………………………………………………. 103

4.1. Строковые типы String, str, &str и &’static str…………………………………………………………………. 104

4.1.1. Сравнение String и str…………………………………………………………………………………………….. 104

4.1.2. Эффективное применение строк……………………………………………………………………………. 105

4.2. Что такое слайсы и массивы?………………………………………………………………………………………….. 108

4.3. Векторы……………………………………………………………………………………………………………………………… 111

4.3.1. Более глубокое погружение в Vec…………………………………………………………………………. 111

4.3.2. Обертывание векторов…………………………………………………………………………………………… 113

4.3.3. Типы, связанные с векторами………………………………………………………………………………… 113

4.4. Отображения……………………………………………………………………………………………………………………… 114

4.4.1. Пользовательские функции хеширования……………………………………………………………. 115

4.4.2. Создание хешируемых типов………………………………………………………………………………… 116

4.5. Типы Rust: примитивы, структуры, перечисления и псевдонимы………………………………… 117

4.5.1. Применение примитивных типов………………………………………………………………………….. 117

Целочисленные типы…………………………………………………………………………………………….. 118

Размерные типы…………………………………………………………………………………………………….. 119

Арифметика на примитивных типах……………………………………………………………………. 119

4.5.2. Использование кортежей……………………………………………………………………………………….. 121

4.5.3. Применение структур…………………………………………………………………………………………….. 122

4.5.4. Применение перечислений…………………………………………………………………………………….. 125

4.5.5. Применение псевдонимов………………………………………………………………………………………. 128

4.6. Обработка ошибок с помощью Result…………………………………………………………………………….. 129

4.7. Преобразование типов с помощью From/Into………………………………………………………………… 130

4.7.1. Типажи TryFrom и TryInto……………………………………………………………………………………… 132

4.7.2. Наиболее рациональные приемы преобразования типов с использованием From и Into   133

4.8. Обеспечение совместимости интерфейса внешних функций с типами Rust………………… 133

Резюме………………………………………………………………………………………………………………………………………. 135

Глава 5. Работа с памятью……………………………………………………………………. 137

5.1. Управление памятью: куча и стек…………………………………………………………………………………… 137

5.2. Представление о владении: копирование, заимствование, ссылки и перемещения……. 140

5.3. Глубокое копирование……………………………………………………………………………………………………… 142

5.4. Предотвращение копирования………………………………………………………………………………………… 144

5.5. Умные указатели: тип Box……………………………………………………………………………………………….. 146

5.6. Подсчет ссылок…………………………………………………………………………………………………………………. 151

5.7. Клонирование при записи………………………………………………………………………………………………… 155

5.8. Пользовательские распределители…………………………………………………………………………………. 159

5.8.1. Создание пользовательского распределителя…………………………………………………….. 160

5.8.2. Создание пользовательского распределителя для защищенной памяти………….. 163

5.9. Кратко об умных указателях…………………………………………………………………………………………… 169

Резюме………………………………………………………………………………………………………………………………………. 170

Часть III. Корректность кода……………………………………………………. 173

Глава 6. Модульное тестирование………………………………………………………… 175

6.1. Чем примечательно тестирование в Rust?………………………………………………………………………. 175

6.2. Встроенные функции тестирования………………………………………………………………………………… 177

6.3. Среды тестирования…………………………………………………………………………………………………………. 179

6.4. Компилятор лучше вас знает, что не нужно тестировать…………………………………………….. 184

6.5. Работа с особыми случаями параллельного тестирования и глобального состояния. 185

6.6. Размышления о реструктуризации………………………………………………………………………………….. 191

6.7. Инструменты реструктуризации……………………………………………………………………………………… 191

6.7.1. Переформатирование…………………………………………………………………………………………….. 192

6.7.2. Переименование……………………………………………………………………………………………………… 192

6.7.3. Перемещение…………………………………………………………………………………………………………… 194

6.7.4. Переписывание……………………………………………………………………………………………………….. 194

6.8. Охват кода…………………………………………………………………………………………………………………………. 196

6.9. Работа с меняющейся экосистемой…………………………………………………………………………………. 198

Резюме………………………………………………………………………………………………………………………………………. 198

Глава 7. Интеграционное тестирование……………………………………………….. 199

7.1. Сравнение интеграционного и модульного тестирования……………………………………………. 200

7.2. Стратегии интеграционного тестирования…………………………………………………………………….. 203

7.3. Сравнение встроенного и внешнего интеграционного тестирования………………………….. 205

7.4. Библиотеки и инструменты для проведения интеграционного тестирования…………….. 206

7.4.1. Использование assert_cmd для тестирования CLI-приложений………………………… 206

7.4.2. Использование с интеграционными тестами крейта proptest…………………………….. 210

7.4.3. Другие инструменты интеграционного тестирования………………………………………… 211

7.5. Fuzz-тестирование…………………………………………………………………………………………………………….. 211

Резюме………………………………………………………………………………………………………………………………………. 216

Часть IV. Асинхронный Rust…………………………………………………….. 217

Глава 8. Асинхронное программирование в Rust………………………………….. 219

8.1. Среды выполнения……………………………………………………………………………………………………………. 221

8.2. Асинхронное мышление…………………………………………………………………………………………………… 222

8.3. Фьючерсы: обработка результатов выполнения асинхронных задач………………………… 224

8.3.1. Режим бездействия…………………………………………………………………………………………………. 224

8.3.2. Определение среды выполнения с помощью #[tokio::main]………………………………. 227

8.4. Ключевые слова async и .await: когда и где их использовать?…………………………………….. 227

8.5. Конкурентность и параллелизм с async………………………………………………………………………….. 230

8.6. Реализация асинхронного наблюдателя………………………………………………………………………… 234

8.7. Смешивание синхронного и асинхронного кода…………………………………………………………… 240

8.8. Когда не стоит применять асинхронность?……………………………………………………………………. 243

8.9. Трассировка и отладка асинхронного кода…………………………………………………………………… 243

8.10. Работа с асинхронностью при тестировании………………………………………………………………. 247

Резюме………………………………………………………………………………………………………………………………………. 248

Глава 9. Создание сервиса HTTP REST API…………………………………………. 251

9.1. Выбор веб-фреймворка…………………………………………………………………………………………………….. 252

9.2. Построение архитектуры…………………………………………………………………………………………………. 253

9.3. Проектирование API…………………………………………………………………………………………………………. 254

9.4. Библиотеки и инструменты……………………………………………………………………………………………… 255

9.5. Создание шаблонов приложений……………………………………………………………………………………. 257

9.5.1. Функция main()……………………………………………………………………………………………………….. 257

9.5.2. Инициализация трассировки: init_tracing()…………………………………………………………. 259

9.5.3. Инициализация пула базы данных: init_dbpool()……………………………………………….. 260

9.6. Моделирование данных…………………………………………………………………………………………………… 262

9.6.1. SQL-схема……………………………………………………………………………………………………………….. 262

9.6.2. Взаимодействие с нашими данными…………………………………………………………………….. 263

9.7. Объявление API-маршрутов…………………………………………………………………………………………….. 267

9.8. Реализация API-маршрутов……………………………………………………………………………………………… 269

9.9. Обработка ошибок……………………………………………………………………………………………………………. 272

9.10. Запуск сервиса………………………………………………………………………………………………………………… 273

Резюме………………………………………………………………………………………………………………………………………. 278

Глава 10. Создание CLI-инструмента HTTP REST API…………………………. 279

10.1. Выбор используемых инструментов и библиотек……………………………………………………….. 280

10.2. Проектирование CLI………………………………………………………………………………………………………. 281

10.3. Объявление команд…………………………………………………………………………………………………………. 282

10.4. Реализация команд…………………………………………………………………………………………………………. 285

10.5. Реализация запросов………………………………………………………………………………………………………. 287

10.6. Надлежащая обработка ошибок…………………………………………………………………………………… 289

10.7. Тестирование нашего CLI……………………………………………………………………………………………… 289

Резюме………………………………………………………………………………………………………………………………………. 293

Часть V. Оптимизация………………………………………………………………… 295

Глава 11. Оптимизация кода………………………………………………………………… 297

11.1. Абстракции с нулевой стоимостью……………………………………………………………………………….. 297

11.2. Векторы……………………………………………………………………………………………………………………………. 299

11.2.1. Выделение памяти для вектора…………………………………………………………………………. 299

11.2.2. Итераторы векторов…………………………………………………………………………………………… 301

11.2.3. Быстрое копирование с помощью Vec и слайсов…………………………………………….. 303

11.3. Применение возможностей SIMD………………………………………………………………………………….. 305

11.4. Распараллеливание с применением Rayon………………………………………………………………….. 307

11.5. Использование Rust для ускорения программ на других языках……………………………….. 309

11.6. Что делать дальше?………………………………………………………………………………………………………… 311

Резюме………………………………………………………………………………………………………………………………………. 312

Приложение…………………………………………………………………………………………. 313

Установка инструментов для примеров, приводимых в книге…………………………………………….. 313

Установка инструментов на macOS с помощью Homebrew………………………………………… 313

Установка инструментов на системах под управлением Linux…………………………………… 313

Установка rustup на Linux- или UNIX-системах…………………………………………………………… 313

Установка инструментов на системах под управлением Windows……………………………… 314

Управление rustc и другими Rust-компонентами с помощью rustup…………………………………… 314

Установка rustc и других компонентов………………………………………………………………………….. 314

Переключение исходных наборов инструментов с помощью rustup………………………….. 315

Обновление Rust-компонентов……………………………………………………………………………………….. 315

Установка HTTPie……………………………………………………………………………………………………………. 315

Предметный указатель…………………………………………………………………………. 317

 

Опубликовано

Новинка: “Rust: атомарности и блокировки”

Rust: атомарности и блокировки

Книга позволяет программистам получить четкое представление о низкоуровневой конкурентности и ее реализации. Даны основы конкурентности в Rust. Раскрыты понятия об  атомарности и упорядочении памяти. Рассмотрены практические аспекты создания своих собственных каналов, своего собственного типа Arc  и своих собственных блокировок  Дано представление о внутренней “кухне” процессора. Рассказано о  примитивах операционной системы.  Предложены идеи для самостоятельной разработки решений,  связанных с вычислениями в конкурентном режиме.

Для Rust-программистов

Mara Bos

Примеры кода, использованные в этой книге, загружены автором в репозиторий на GitHub для вашего ознакомления: https://github.com/m-ou-se/rust-atomics-and-locks.

Низкоуровневая конкурентность на практике (Low-Level Concurrency in Practice)

Вы изучите применение Rust в следующих областях:

Язык программирования Rust великолепно справляется с конкурентными вычислениями, а в его экосистеме имеется множество библиотек, включающих широкий набор структур данных, блокировок и многого другого, предназначенного для работы в среде конкурирующих потоков. Но корректная реализация этих структур может оказаться весьма непростой задачей. Ошибки, допущенные в вопросах упорядочения памяти, нередко встречаются даже в самых востребованных библиотеках.

В этой книге, имеющей сугубо практическую направленность, Мара Бос, руководитель команды разработчиков библиотеки Rust, помогает Rust-программистам всех уровней получить четкое представление о низкоуровневой конкурентности. Вы узнаете об атомарности и упо-рядочении памяти, а также о том, как они сочетаются с базовыми API-интерфейсами опера-ционной системы для создания таких наиболее востребованных примитивов, как мьютексы и условные переменные. Прочитав книгу, вы получите четкое представление о том, как связаны друг с другом используемая в Rust модель памяти, процессор и особенности той или иной операционной системы.

Вы узнаете:

  • Об исключительной роли имеющейся в Rust сиcтемы типов в корректном программировании конкурентности
  • Все о мьютексах, условных переменных, атомарности и упорядочении памяти
  • Что на самом деле происходит с атомарными операциями в процессорах Intel и ARM
  • Как реализуются блокировки при поддержке операционной системы
  • Как создается корректный программный код, включающий конкурентность, атомарность и блокировки
  • Какими приемами можно воспользоваться для правильного создания своих собственных примитивов  блокировки и синхронизации

Это удивительная книга! В ней именно то, что мне самой хотелось рассказать о конкурентно-сти, но у Мары получилось гораздо лучше, о чем я даже не смела мечтать. Досконально и все на своих местах.
Ария Бейнжеснер, автор книги “The Rustonomicon”

Книгу “Rust: атомарности и блокировки” можно купить со скидкой в интернет-магазине издательства “БХВ“.

Предисловие…………………………………………………………………………………………… 11

Введение………………………………………………………………………………………………… 13

Для кого предназначена эта книга…………………………………………………………………………………………… 13

Обзор глав…………………………………………………………………………………………………………………………………… 14

Примеры кода…………………………………………………………………………………………………………………………….. 16

Условные обозначения, используемые в данной книге………………………………………………………….. 16

Благодарности…………………………………………………………………………………………………………………………… 17

Глава 1. Основы конкурентности в Rust………………………………………………… 19

Потоки в Rust……………………………………………………………………………………………………………………………… 19

Потоки с областью действия…………………………………………………………………………………………………….. 23

Совместное владение и подсчет ссылок………………………………………………………………………………….. 25

Статика…………………………………………………………………………………………………………………………………. 25

Утечка……………………………………………………………………………………………………………………………………. 25

Подсчет ссылок…………………………………………………………………………………………………………………….. 26

Заимствования и гонка данных………………………………………………………………………………………………… 28

Внутренняя изменяемость…………………………………………………………………………………………………………. 30

Cell…………………………………………………………………………………………………………………………………………. 31

RefCell……………………………………………………………………………………………………………………………………. 32

Mutex и RwLock…………………………………………………………………………………………………………………….. 33

Атомарные типы…………………………………………………………………………………………………………………… 33

UnsafeCell……………………………………………………………………………………………………………………………… 34

Потокобезопасность: Send и Sync…………………………………………………………………………………………….. 34

Блокировка: мьютексы и RwLock-блокировки………………………………………………………………………… 36

Мьютекс в языке Rust…………………………………………………………………………………………………………… 37

Отравление блокировок………………………………………………………………………………………………………. 39

Блокировка чтения-записи………………………………………………………………………………………………….. 41

Ожидание: парковка и условные переменные………………………………………………………………………… 42

Парковка потоков…………………………………………………………………………………………………………………. 42

Условные переменные…………………………………………………………………………………………………………. 45

Резюме…………………………………………………………………………………………………………………………………………. 47

Глава 2. Атомарность…………………………………………………………………………….. 48

Атомарные операции загрузки и сохранения: load и store……………………………………………………. 49

Пример: Флаг остановки……………………………………………………………………………………………………… 49

Пример: Отчет о ходе выполнения задачи………………………………………………………………………… 50

Синхронизация………………………………………………………………………………………………………….. 51

Пример: Отложенная инициализация………………………………………………………………………………… 52

Операции выборки и изменения……………………………………………………………………………………………….. 54

Пример: Отчет о ходе выполнения задачи из нескольких потоков…………………………………. 55

Пример: Статистика…………………………………………………………………………………………………………….. 56

Пример: Предоставление идентификатора……………………………………………………………………….. 58

Операции сравнения и обмена………………………………………………………………………………………………….. 60

Пример: Предоставление идентификатора без переполнения…………………………………………. 62

Пример: Отложенная однократная инициализация………………………………………………………….. 63

Резюме…………………………………………………………………………………………………………………………………………. 64

Глава 3. Упорядочение памяти………………………………………………………………. 66

Изменение порядка и оптимизация…………………………………………………………………………………………… 66

Модель памяти…………………………………………………………………………………………………………………………… 68

Отношения “происходит до”…………………………………………………………………………………………………….. 68

Порождение и присоединение…………………………………………………………………………………………….. 70

Расслабленное упорядочение…………………………………………………………………………………………………… 71

Упорядочение высвобождения и получения памяти………………………………………………………………. 73

Пример: Блокировка…………………………………………………………………………………………………………….. 76

Пример: Отложенная инициализация с применением косвенного подхода…………………… 78

Упорядочение потребления………………………………………………………………………………………………………. 81

Последовательно согласованное упорядочение…………………………………………………………………….. 82

Ограждения………………………………………………………………………………………………………………………………… 83

Распространенные заблуждения……………………………………………………………………………………………… 87

Резюме…………………………………………………………………………………………………………………………………………. 89

Глава 4. Создание своей собственной спин-блокировки………………………… 91

Минималистичная реализация…………………………………………………………………………………………………. 91

Небезопасная спин-блокировка……………………………………………………………………………………………….. 93

Безопасный интерфейс с использованием хранителя блокировки……………………………………….. 96

Резюме…………………………………………………………………………………………………………………………………………. 99

Глава 5. Создание своих собственных каналов……………………………………. 100

Простой канал на основе мьютекса……………………………………………………………………………………….. 100

Небезопасный одноразовый канал………………………………………………………………………………………… 102

Безопасность, достигаемая проверками в ходе выполнения……………………………………………….. 105

Обеспечение безопасности с использованием системы типов…………………………………………….. 109

Заимствование во избежание выделения памяти………………………………………………………………….. 114

Блокировка……………………………………………………………………………………………………………………………….. 117

Резюме………………………………………………………………………………………………………………………………………. 119

Глава 6. Создание своего собственного типа Arc………………………………….. 121

Базовый подсчет ссылок…………………………………………………………………………………………………………. 121

Тестирование……………………………………………………………………………………………………………………… 125

Изменение……………………………………………………………………………………………………………………………. 126

Слабые указатели……………………………………………………………………………………………………………………. 127

Тестирование……………………………………………………………………………………………………………………… 132

Оптимизация…………………………………………………………………………………………………………………………….. 133

Резюме………………………………………………………………………………………………………………………………………. 140

Глава 7. Представление о внутренней “кухне” процессора………………….. 141

Инструкции процессора………………………………………………………………………………………………………….. 142

Загрузка и сохранение………………………………………………………………………………………………………. 145

Операции чтения-изменения-записи…………………………………………………………………………………. 147

Префикс lock в x86…………………………………………………………………………………………………… 147

x86-инструкция сравнения-обмена……………………………………………………………………….. 149

Инструкции load-linked и store-conditional……………………………………………………………………… 150

ARM-инструкции load-exclusive и store-exclusive………………………………………………… 151

ARM-инструкции сравнения-обмена…………………………………………………………………….. 152

Кеширование……………………………………………………………………………………………………………………………. 154

Согласованность кеша………………………………………………………………………………………………………. 155

Протокол сквозной записи……………………………………………………………………………………… 156

Протокол MESI……………………………………………………………………………………………………….. 156

Влияние, оказываемое на производительность………………………………………………………………. 157

Переупорядочение…………………………………………………………………………………………………………………… 162

Упорядочение памяти……………………………………………………………………………………………………………… 164

x86-64: строго упорядоченная архитектура……………………………………………………………………. 165

ARM64: слабо упорядоченная архитектура…………………………………………………………………… 167

Эксперимент……………………………………………………………………………………………………………………….. 169

Ограждения памяти……………………………………………………………………………………………………………. 171

Резюме………………………………………………………………………………………………………………………………………. 172

Глава 8. Примитивы операционной системы……………………………………….. 175

Взаимодействие с ядром…………………………………………………………………………………………………………. 175

POSIX………………………………………………………………………………………………………………………………………… 176

Обертывание в Rust……………………………………………………………………………………………………………. 178

Linux………………………………………………………………………………………………………………………………………….. 180

Фьютекс………………………………………………………………………………………………………………………………. 180

Фьютексные операции……………………………………………………………………………………………………….. 183

Фьютексные операции с наследованием приоритета…………………………………………………….. 187

macOS……………………………………………………………………………………………………………………………………….. 188

os_unfair_lock…………………………………………………………………………………………………………………….. 189

Windows…………………………………………………………………………………………………………………………………….. 189

Тяжеловесные объекты ядра…………………………………………………………………………………………….. 189

Облегченные объекты………………………………………………………………………………………………………… 190

Легкая блокировка чтения-записи…………………………………………………………………………. 190

Адресное ожидание……………………………………………………………………………………………………………. 191

Резюме………………………………………………………………………………………………………………………………………. 192

Глава 9. Создание своих собственных блокировок………………………………. 194

Мьютекс……………………………………………………………………………………………………………………………………. 196

Предотвращение системных вызовов………………………………………………………………………………. 199

Дальнейшая оптимизация…………………………………………………………………………………………………. 201

Сравнительный анализ……………………………………………………………………………………………………… 203

Условная переменная………………………………………………………………………………………………………………. 205

Предотвращение системных вызовов………………………………………………………………………………. 210

Предотвращение ложных пробуждений………………………………………………………………………….. 212

Блокировка чтения-записи……………………………………………………………………………………………………… 215

Предотвращение применения ждущего цикла в записывающих потоках……………………. 218

Предотвращение голода записывающих потоков………………………………………………………….. 220

Резюме………………………………………………………………………………………………………………………………………. 224

Глава 10. Идеи и творческое воодушевление……………………………………….. 225

Семафор……………………………………………………………………………………………………………………………………. 225

RCU…………………………………………………………………………………………………………………………………………… 226

Связанный список без блокировки…………………………………………………………………………………………. 227

Блокировки на основе очереди………………………………………………………………………………………………. 228

Блокировки на основе парковок…………………………………………………………………………………………….. 229

Последовательная блокировка………………………………………………………………………………………………. 230

Учебные материалы………………………………………………………………………………………………………………… 231

Предметный указатель…………………………………………………………………………. 233

Об авторе……………………………………………………………………………………………… 237

Об изображении на обложке………………………………………………………………… 238

 

 

 

Mara Bos

Примеры кода, использованные в этой книге, загружены автором в репозиторий на GitHub для вашего ознакомления: https://github.com/m-ou-se/rust-atomics-and-locks.