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

Представляем книгу “Расширения ядра Linux: драйверы и модули”

Расширения ядра Linux: драйверы и модули

Представляем книгу Олега Цилюрика “Расширения ядра Linux: драйверы и модули”. В книге подробно рассмотрено программирование драйверов ядра Linux, исследованы возможности расширяемости ядра при помощи модулей. Основная версия ядра – 5.15. Код примеров отработан и проверен на десятках различных инсталляций Linux, установленных из различных дистрибутивов и разных семейств дистрибутивов: Fedora, CentOS, Debian, Ubuntu, Mint. Уделено внимание архитектурам x_64, x_86, ARM, а также одноплатному компьютеру Raspberry Pi и драйверам устройств, подключаемых по USB. Затронут стандарт POSIX, разобраны API ядра, работа с Raspberry Pi, системные вызовы и подключение разнообразных периферийных устройств.

 

Ядро Linux — шедевр низкоуровневого кода на языке C. Разработка ядра не прекращается уже почти 30 лет, и занимается этим глобальное сообщество энтузиастов и профессионалов. Системные вызовы ядра Linux, тонкости управления памятью или параллельная обработка запросов – все эти темы важны сами по себе и в совокупности, но есть и ещё одна важная тема, до сих пор освещённая на русском языке фрагментарно и неравномерно: программирование драйверов и модулей ядра.

Именно этой теме посвящён фундаментальный труд, впервые публикуемый в качестве отдельной книги. Он зародился в начале 2000-х как материал для корпоративного курса и постоянно обновлялся вплоть до ноября 2022 года – и в данной версии выходит на бумаге. Новейшая версия ядра, учтённая в книге, – 5.15.

В книге подробно разобраны API ядра, системные вызовы, обработка сигналов, взаимодействия с периферийными устройствами и, в частности, с протоколом USB. Уделено внимание процессорным архитектурам x_64, x_86, ARM, а также одноплатному компьютеру Raspberry Pi и драйверам внешних устройств. Рассмотрена конфигурация и загрузка модулей и всевозможные варианты кастомизации ядра, рассмотрен стандарт POSIX.

Книга ориентирована на опытных программистов и системных администраторов, работающих с Linux. Призвана послужить достойным аналогом и дополнением классической работы «Драйверы устройств Linux. 3-е издание» Джонатана Корбетта и соавторов (Corbet J., Rubini A., Kroah-Hartman G. Linux Device Drivers, 3rd Edition).

Хорошая книга не дарит тебе откровение, хорошая книга укрепляет тебя в твоих самостоятельных догадках.
Андрей Рубанов, «Хлорофилия»

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

От автора……………………………………………………………………………………………….. 11

Предыстория………………………………………………………………………………………………………………………………. 11

Кому адресована книга?…………………………………………………………………………………………………………… 13

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

Соглашения, принятые в тексте………………………………………………………………………………………………… 18

Код примеров и замеченные опечатки…………………………………………………………………………………….. 19

Замечания о версиях ядра…………………………………………………………………………………………………………. 22

Обновляемость ядра………………………………………………………………………………………………………………….. 23

Использованные источники информации………………………………………………………………………………… 25

Обновления текущей редакции текста…………………………………………………………………………………….. 25

Глава 1. Модули с высоты птичьего полёта…………………………………………… 27

Linux и GNU………………………………………………………………………………………………………………………………… 27

FAQ                                                                                                                                                                   28

Модуль в иерархии программных систем……………………………………………………………………………….. 29

Наш первый модуль ядра………………………………………………………………………………………………………….. 31

Сборка модуля……………………………………………………………………………………………………………………. 31

Загрузка и исполнение………………………………………………………………………………………………………. 33

Точки входа и завершения………………………………………………………………………………………………… 34

Внутренний формат модуля……………………………………………………………………………………………………… 36

Диагностика модуля………………………………………………………………………………………………………………….. 38

Уровни диагностики в /proc………………………………………………………………………………………………. 42

Представление адресов в Linux………………………………………………………………………………………… 43

Форматы вывода………………………………………………………………………………………………………………… 45

Основные ошибки модуля…………………………………………………………………………………………………………. 48

Обсуждение………………………………………………………………………………………………………………………………… 50

Глава 2. Архитектура и вокруг………………………………………………………………. 53

Ядро: монолитное и микроядро……………………………………………………………………………………………….. 53

Траектория системного вызова………………………………………………………………………………………………… 55

Библиотечный и системный вызов из процесса………………………………………………………………. 56

Под капотом системного вызова………………………………………………………………………………………. 63

Отслеживание системного вызова в процессе…………………………………………………………………. 66

Различия программ пространств ядра и пользователя………………………………………………………….. 67

Интерфейсы модуля…………………………………………………………………………………………………………………… 70

Взаимодействие модуля с уровнем пользователя…………………………………………………………… 70

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

Коды ошибок………………………………………………………………………………………………………………………. 77

Загрузка модулей………………………………………………………………………………………………………………………. 77

Автоматическая загрузка модулей…………………………………………………………………………………… 78

Запрет загрузки (черный список модулей)………………………………………………………………………. 79

Параметры загрузки модуля…………………………………………………………………………………………………….. 80

Конфигурационные параметры ядра………………………………………………………………………………………. 85

Параметры в ядре………………………………………………………………………………………………………………. 85

Параметры в модуле………………………………………………………………………………………………………….. 88

Подсчет ссылок использования………………………………………………………………………………………………… 91

Обсуждение………………………………………………………………………………………………………………………………… 93

Глава 3. Инструментальное окружение………………………………………………….. 95

Основные команды…………………………………………………………………………………………………………………….. 95

Системные файлы………………………………………………………………………………………………………………………. 96

Графика, терминал и текстовая консоль…………………………………………………………………………………. 99

Управление текстовыми консолями……………………………………………………………………………………….. 100

Коротко о компиляторе GCC………………………………………………………………………………………………….. 102

Ассемблер в Linux……………………………………………………………………………………………………………………. 105

Нотация AT&T…………………………………………………………………………………………………………………. 107

Инлайновый ассемблер GCC………………………………………………………………………………………….. 108

Создание среды сборки модулей ядра…………………………………………………………………………………… 110

Работа над кодом…………………………………………………………………………………………………………………….. 114

В деталях о сборке…………………………………………………………………………………………………………………… 117

Переменные периода компиляции………………………………………………………………………………….. 117

Дополнительные параметры периода компиляции………………………………………………………. 118

Версионность ядра в коде модуля………………………………………………………………………………….. 118

Как собрать одновременно несколько модулей?………………………………………………………….. 120

Как собрать модуль и используемые программы к нему?……………………………………………. 120

Пользовательские библиотеки………………………………………………………………………………………… 121

Как собрать модуль из нескольких объектных файлов?………………………………………………. 123

Рекурсивная сборка…………………………………………………………………………………………………………. 125

Подписывание модулей…………………………………………………………………………………………………………… 127

Инсталляция модуля……………………………………………………………………………………………………………….. 130

Нужна ли новая сборка ядра?………………………………………………………………………………………………… 131

Динамическая сборка модулей (DKMS)………………………………………………………………………………… 133

Обсуждение………………………………………………………………………………………………………………………………. 138

Глава 4. Внешние интерфейсы модуля…………………………………………………. 139

Драйверы: интерфейс устройства………………………………………………………………………………………….. 139

Символьные устройства………………………………………………………………………………………………….. 143

Варианты реализации……………………………………………………………………………………………. 145

Ручное создание имени………………………………………………………………………………….. 146

Использование udev……………………………………………………………………………………….. 151

Динамические имена………………………………………………………………………………………. 155

Разнородные (смешанные) устройства………………………………………………………… 159

Управляющие операции устройства…………………………………………………………………….. 162

Множественное открытие устройства………………………………………………………………….. 169

Счетчик ссылок использования модуля……………………………………………………………….. 177

Режимы выполнения операций ввода/вывода……………………………………………………… 180

Неблокирующий ввод/вывод и мультиплексирование……………………………………….. 181

Блочные устройства………………………………………………………………………………………………………… 190

Особенности драйвера блочного устройства………………………………………………………. 193

Обзор примеров реализации………………………………………………………………………………….. 194

Регистрация устройства…………………………………………………………………………………………. 195

Подготовка к регистрации……………………………………………………………………………… 195

Диски с разметкой MBR и GPT……………………………………………………………………… 197

Заполнение структуры…………………………………………………………………………………… 199

Завершение регистрации……………………………………………………………………………….. 201

Таблица операций устройства………………………………………………………………………………. 201

Обмен данными……………………………………………………………………………………………………….. 205

Классика: очередь и обслуживание ядром………………………………………………….. 210

Очередь и обработка запроса в драйвере……………………………………………………. 212

Отказ от очереди…………………………………………………………………………………………….. 214

Пример перманентных данных……………………………………………………………………… 215

Некоторые важные API………………………………………………………………………………….. 215

Результаты тестирования………………………………………………………………………………………. 216

Файловая система FUSE…………………………………………………………………………………………. 221

Интерфейс /proc……………………………………………………………………………………………………………………….. 228

Терминальные значения в /proc и /sys……………………………………………………………………………. 230

Использование /proc………………………………………………………………………………………………………… 231

Специфический механизм procfs……………………………………………………………………………. 232

Варианты реализации чтения……………………………………………………………………….. 240

Запись данных………………………………………………………………………………………………… 244

Общий механизм файловых операций………………………………………………………………….. 245

Интерфейс /sys………………………………………………………………………………………………………………………….. 251

Создание и использование имен в /sys……………………………………………………………………………. 253

Ошибки обменных операций…………………………………………………………………………………………… 261

Сетевые интерфейсы и протоколы…………………………………………………………………………………………. 263

Сетевые инструменты……………………………………………………………………………………………………… 265

Сетевые интерфейсы………………………………………………………………………………………………. 265

Инструменты наблюдения……………………………………………………………………………………… 269

Инструменты интегрального тестирования…………………………………………………………. 276

Структуры данных сетевого стека…………………………………………………………………………………. 278

Драйверы: сетевой интерфейс………………………………………………………………………………………… 279

Создание сетевых интерфейсов…………………………………………………………………………….. 279

Новая схема, и детальнее о ее создании………………………………………………………………. 281

Операции сетевого интерфейса……………………………………………………………………………… 286

Переименование сетевого интерфейса………………………………………………………………….. 291

Путь пакета сквозь стек протоколов………………………………………………………………………………. 293

Прием: традиционный подход………………………………………………………………………………. 293

Прием: высокоскоростной интерфейс…………………………………………………………………… 294

Передача пакетов……………………………………………………………………………………………………. 297

Статистика интерфейса…………………………………………………………………………………………………… 298

Виртуальный сетевой интерфейс……………………………………………………………………………………. 301

Протокол сетевого уровня………………………………………………………………………………………………. 307

Еще раз о виртуальном интерфейсе……………………………………………………………………………….. 314

Протокол транспортного уровня……………………………………………………………………………………. 321

Использование драйверов Windows……………………………………………………………………………….. 323

Обсуждение………………………………………………………………………………………………………………………. 324

Глава 5. Внутренние API ядра………………………………………………………………. 326

Механизмы управления памятью…………………………………………………………………………………………… 326

Карта памяти……………………………………………………………………………………………………………………. 326

Динамическое выделение памяти…………………………………………………………………………………… 330

Распределители памяти…………………………………………………………………………………………………… 334

Слябовый распределитель………………………………………………………………………………………………. 336

Страничное выделение……………………………………………………………………………………………………. 344

Выделение больших буферов…………………………………………………………………………………………. 344

Динамические структуры и управление памятью………………………………………………………… 345

Циклический двусвязный список…………………………………………………………………………… 345

Модуль, использующий динамические структуры……………………………………………… 349

Сложноструктурированные данные…………………………………………………………………….. 351

Еще об инициализации объектов ядра………………………………………………………………….. 351

Служба времени………………………………………………………………………………………………………………………. 352

Информация о времени в ядре…………………………………………………………………………………………. 352

Источник прерываний системного таймера…………………………………………………………. 355

Дополнительные источники информации о времени…………………………………………… 356

Три класса задач во временной области……………………………………………………………………….. 357

Измерения временных интервалов…………………………………………………………………………………. 358

Временные задержки……………………………………………………………………………………………………….. 365

Таймеры ядра…………………………………………………………………………………………………………………… 371

Таймеры высокого разрешения………………………………………………………………………………………. 372

Абсолютное время……………………………………………………………………………………………………………. 375

Часы реального времени (RTC)………………………………………………………………………………………. 376

Время и диспетчеризация в ядре…………………………………………………………………………………….. 381

Параллелизм и синхронизация………………………………………………………………………………………………. 382

Потоки ядра………………………………………………………………………………………………………………………. 385

Создание потока ядра…………………………………………………………………………………………….. 385

Свойства потока……………………………………………………………………………………………………… 387

Новый интерфейс потоков……………………………………………………………………………………… 389

Синхронизация завершения…………………………………………………………………………………… 394

Синхронизация в коде……………………………………………………………………………………………………… 401

Критические секции кода и защищаемые области данных………………………………… 401

Механизмы синхронизации…………………………………………………………………………………… 402

Условные переменные и ожидание завершения…………………………………………………… 402

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

Битовые атомарные операции………………………………………………………………………. 405

Арифметические атомарные операции………………………………………………………… 406

Локальные переменные процессора……………………………………………………………………… 407

Предыдущая модель………………………………………………………………………………………. 407

Новая модель………………………………………………………………………………………………….. 408

Блокировки………………………………………………………………………………………………………………. 409

Семафоры и мьютексы…………………………………………………………………………………… 410

Спин-блокировки……………………………………………………………………………………………. 415

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

Сериальные (последовательные) блокировки……………………………………………… 420

Мьютексы реального времени………………………………………………………………………. 422

Инверсия и наследование приоритетов………………………………………………………… 422

Множественное блокирование………………………………………………………………………………. 423

Уровень блокирования…………………………………………………………………………………………… 424

Предписание порядка выполнения……………………………………………………………………….. 430

Аннотация ветвлений……………………………………………………………………………………… 430

Барьеры…………………………………………………………………………………………………………… 431

Обработка прерываний…………………………………………………………………………………………………………… 432

Общая модель обработки прерывания…………………………………………………………………………… 433

Наблюдение прерываний в /proc……………………………………………………………………………………. 436

Регистрация обработчика прерывания………………………………………………………………………….. 439

Обработчик прерываний: верхняя половина………………………………………………………………… 442

Управление линиями прерывания…………………………………………………………………………. 444

Пример обработчика прерываний………………………………………………………………………… 444

Отложенная обработка: нижняя половина……………………………………………………………………. 446

Отложенные прерывания: softirq…………………………………………………………………………… 446

Тасклеты………………………………………………………………………………………………………………….. 450

Демон ksoftirqd………………………………………………………………………………………………………… 452

Очереди отложенных действий: workqueue…………………………………………………………. 452

Сравнение и примеры…………………………………………………………………………………………….. 455

Обсуждение………………………………………………………………………………………………………………………. 460

Глава 6. Периферийные устройства в модулях ядра…………………………….. 466

Поддержка шинных устройств в модуле……………………………………………………………………………….. 466

Анализ оборудования……………………………………………………………………………………………………………… 468

Подсистема udev………………………………………………………………………………………………………………. 473

Идентификация модуля……………………………………………………………………………………………………. 477

Ошибки идентификации модуля……………………………………………………………………………………… 479

Устройства на шине PCI…………………………………………………………………………………………………………. 480

Подключение к линии прерывания…………………………………………………………………………………. 491

Отображение памяти……………………………………………………………………………………………………….. 492

DMA…………………………………………………………………………………………………………………………………… 493

Устройства USB……………………………………………………………………………………………………………………….. 499

Некоторые технические детали……………………………………………………………………………………… 499

Поддержка в Linux…………………………………………………………………………………………………………… 501

Пара слов о USB-модемах………………………………………………………………………………………………. 503

Устройства USB в коде модуля………………………………………………………………………………………. 506

Многофункциональные USB-устройства………………………………………………………………………. 514

Устройства в пространстве пользователя…………………………………………………………………………….. 520

Аппаратные порты…………………………………………………………………………………………………………… 521

Особенности доступа………………………………………………………………………………………………………. 526

Проект libusb…………………………………………………………………………………………………………………….. 527

GPIO…………………………………………………………………………………………………………………………………… 536

Глава 7. Расширенные возможности программирования……………………… 543

Операции с файлами данных………………………………………………………………………………………………….. 544

Запуск новых процессов из ядра……………………………………………………………………………………………. 552

Сигналы UNIX………………………………………………………………………………………………………………………….. 554

Вокруг экспорта символов ядра…………………………………………………………………………………………….. 561

Неэкспортируемые символы ядра………………………………………………………………………………….. 564

Использование неэкспортируемых символов……………………………………………………………….. 572

Подмена системных вызовов…………………………………………………………………………………………… 576

Добавление новых системных вызовов………………………………………………………………………….. 584

Скрытый обработчик системного вызова……………………………………………………………………… 591

Динамическая загрузка модулей……………………………………………………………………………………………. 600

…из процесса пользователя…………………………………………………………………………………………….. 601

…из модуля ядра……………………………………………………………………………………………………………….. 609

Подключаемые плагины………………………………………………………………………………………………….. 613

Обсуждение………………………………………………………………………………………………………………………………. 623

Глава 8. Отладка в ядре……………………………………………………………………….. 628

Отладочная печать………………………………………………………………………………………………………………….. 629

Интерактивные отладчики……………………………………………………………………………………………………… 629

Отладка в виртуальной машине…………………………………………………………………………………………….. 632

Отдельные отладочные приемы и трюки………………………………………………………………………………. 635

Модуль, исполняемый как разовая задача……………………………………………………………………. 635

Тестирующий модуль………………………………………………………………………………………………………. 637

Интерфейсы пространства пользователя к модулю……………………………………………………… 640

Комплементарный отладочный модуль………………………………………………………………………… 642

Пишите в файлы протоколов…………………………………………………………………………………………… 645

Некоторые мелкие советы в завершение……………………………………………………………………….. 645

Чаще перезагружайте систему!……………………………………………………………………………… 645

Используйте естественные POSIX-тестеры………………………………………………………….. 646

Тестируйте чтение сериями……………………………………………………………………………………. 646

Заключение………………………………………………………………………………………….. 647

Приложение 1. Краткая справка по утилите make………………………………… 649

Приложение 2. Тесты распределителя памяти………………………………………. 652

Приложение 3. Четыре способа записи в защищенную страницу…………. 666

Описание проблемы………………………………………………………………………………………………………………… 666

Отключение страничной защиты: ассемблер……………………………………………………………………….. 667

Отключение страничной защиты: API ядра………………………………………………………………………….. 668

Снятие защиты со страницы памяти……………………………………………………………………………………… 670

Наложение отображения участка памяти…………………………………………………………………………….. 671

Тест выполнения………………………………………………………………………………………………………………………. 672

Обсуждение………………………………………………………………………………………………………………………………. 674

Позднее дополнение………………………………………………………………………………………………………………… 675

Источники информации……………………………………………………………………….. 677

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

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

Цилюрик Олег Иванович

Цилюрик Олег Иванович — программист-разработчик с более чем 40-летним опытом, преподаватель, автор нескольких книг по Linux и Unix, высоко оцененных профессионалами и широкой читательской аудиторией.

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

Вышла книга “Linux и Go. Эффективное низкоуровневое программирование”

Linux и Go. Эффективное низкоуровневое программирование

Первая русскоязычная книга об интеграции языка Go в архитектуру ядра Linux. Содержит вводный курс по языку Go для системного программирования, описывает применение Go для реализации конкурентности и параллелизма, рассказывает об интероперабельности между имеющимся кодом на C с новым кодом на Go, а также исследует возможности внедрения Go для повышения производительности различных дистрибутивов.

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

 

Ядро операционной системы Linux и множество модулей для различных дистрибутивов написаны на языке C. Притом, что язык С продолжает развиваться и активно использоваться на практике, в область системного программирования постепенно проникают и более молодые языки, в частности Go.

Перед вами – первая фундаментальная книга об использовании Go в Linux. Здесь вы познакомитесь с основами системного программирования, изучите детали взаимодействия между ядром и пользовательским пространством Linux, а также узнаете об интероперабельности между С и Go, о том, в каких аспектах и нюансах Linux язык Go может заменить и уже заменяет язык C. Особое внимание уделено конкурентности, параллелизму и стандарту POSIX. В конце книги для закрепления материала приведены реализации нескольких популярных алгоритмов.

Цилюрик Олег Иванович

Цилюрик Олег Иванович — программист-разработчик с более чем 40-летним опытом, преподаватель, автор нескольких книг по Linux и Unix, высоко оцененных профессионалами и широкой читательской аудиторией.

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

Предисловие. 7

Предназначение и целевая аудитория. 7

Код примеров и замеченные опечатки. 9

Соглашения и выделения, принятые в тексте. 10

Напоминание. 11

Источники информации. 11

Часть I. Инструментарий языка Go. 13

Глава 1. Предыстория Go. 15

«Отцы-основатели» о целях и мотивации…… 15

Применимость: беглый взгляд. 16

Go, C, C++ и другие…… 17

Источники информации. 22

Глава 2. Разворачиваем экосистему Go. 23

Создание среды. 23

Стандартная инсталляция. 23

Версии среды. 25

Альтернативы. 26

«Самая последняя» версия. 27

Смена версий. 30

Проверяем: простейшая программа. 30

Проверяем на простейшем приложении. 32

Библиотеки статические и динамические. 34

Компиляция или интерпретация. 34

Выбор: GoLang или GCC?. 35

Инфраструктура GoLang. 36

Команды go. 36

Переменные окружения. 39

Платформы, переносимость и кросс-компиляция. 47

Стиль кодирования (автоформатирование — fmt) 49

Сборка приложений (build) 51

Сценарии на языке Go (run) 51

Загрузка проектов из сети (get) 52

Утилиты GoLang (tool) 57

Связь с кодом C (Cgo) 60

Сторонний и дополнительный инструментарий. 63

Источники информации. 65

Глава 3. Неформально о синтаксисе Go. 66

Типы данных. 71

Переменные. 73

Выполнение такого приложения. 74

Повторные декларации и переприсваивания. 76

Константы. 77

Агрегаты данных. 79

Массивы и срезы. 79

Двухмерные массивы и срезы. 84

Структуры. 85

Таблицы (хэши) 87

Динамическое создание переменных. 89

Конструкторы и составные литералы. 90

Операции. 91

Функции. 94

Вариативные функции. 98

Стек процедур завершения. 100

Обобщенные функции. 101

Функции высших порядков. 102

Встроенные функции. 104

Объектно-ориентированное программирование. 106

Методы. 107

Интерфейсы. 113

Обработка ошибочных ситуаций. 117

Структура пакетов (библиотек) Go. 121

Функция init 125

Импорт для использования побочных эффектов. 126

Некоторые полезные и интересные стандартные пакеты. 126

Пакет runtime. 127

Форматированный ввод-вывод. 128

Строки и пакет strings 129

Большие числа. 134

Автоматизированное тестирование. 135

Источники информации. 135

Часть II. Конкурентность и многопроцессорность. 137

Глава 4. Процессоры в Linux. 139

Процессоры, ядра и гипертрэдинг. 142

Загадочная нумерация процессоров. 144

Управление процессорами Linux. 147

Привязка к процессору. 147

Как происходит диспетчирование в Linux. 150

Источники информации. 156

Глава 5. Параллелизм и многопроцессорность. 157

Эволюция модели параллелизма. 157

Параллельные процессы и fork. 157

Потоки ядра и pthread_t POSIX.. 160

Сопрограммы — модель параллелизма Go. 166

Параллелизм в Go. 167

Сопрограммы — как это выглядит. 168

Возврат значений функцией. 171

Ретроспектива: сопрограммы в C++. 172

Каналы. 172

Функциональные замыкания в сопрограммах. 177

Примитивы синхронизации. 179

Конкурентность и параллельность. 185

Источники информации. 190

Глава 6. Масштабирование. 191

Планирование активности сопрограмм. 191

Испытательный стенд. 193

Микрокомпьютеры (Single-Board Computers) 193

Рабочие десктопы. 196

Серверы промышленного класса. 197

Масштабирование в реале. 198

1-я попытка …… 199

2-й подход к снаряду…… 205

О числе потоков исполнения. 213

Источники информации. 217

Часть III. Некоторые примеры и сравнения. 219

Глава 7. Осваиваемся в синтаксисе Go. 221

Утилита echo. 221

Итерационное вычисление вещественного корня. 223

Вычисление числа π. 225

Случайная последовательность и ее моменты. 227

Обсчет параметров 2D выпуклых многоугольников. 230

Тривиальный web-сервер. 235

Источники информации. 236

Глава 8. Структуры данных, типы и их методы.. 237

Массивы и срезы. 237

Многомерные срезы и массивы. 242

Функции с множественным возвратом. 243

Глава 9. Элементы функционального программирования. 246

Функциональные замыкания. 246

Карринг. 253

Рекурсия. 255

Рекурсия с кэшированием. 255

Чистые функции. 257

Источники информации. 257

Глава 10. Скоростные и другие сравнения языков. 258

Алгоритмические задачи для сравнения. 258

Некоторые известные алгоритмы. 259

Числа Фибоначчи. 260

Пузырьковая сортировка. 263

Ханойская башня. 268

Решето Эратосфена. 272

Глава 11. Многопроцессорные параллельные вычисления. 276

Скорость активации параллельных ветвей. 276

Гонки. 281

Защита критических данных. 285

Многопроцессорный брутфорс. 289

Каналы в сопрограммах. 295

Таймеры. 296

Тикеры. 298

Когда не нужно злоупотреблять многопроцессорностью.. 299

Источники информации. 302

Заключение. 303

Об авторе. 304