---
description: 'Заметки о блокировках'
next: books/arch-handbook/kobj
params:
  path: /books/arch-handbook/locking/
prev: books/arch-handbook/boot
showBookMenu: 'true'
tags: ["locking", "notes", "SMP", "Mutexes"]
title: 'Глава 2. Заметки о блокировках'
weight: 3
---

[[locking]]
= Заметки о блокировках
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumoffset: 2
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/arch-handbook/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

_Эта глава сопровождается и поддерживается проектом FreeBSD SMP Next Generation._

Этот документ описывает механизмы блокировки, используемые в ядре FreeBSD для эффективной многопроцессорной обработки. Блокировка может быть достигнута несколькими способами. Структуры данных могут защищаться мьютексами или блокировками (lock) из man:lockmgr[9]. Некоторые переменные защищаются просто за счёт использования атомарных операций для доступа к ним.

[[locking-mutexes]]
== Mutexes

Мьютекс — это просто блокировка, используемая для обеспечения взаимного исключения. Конкретно, мьютекс может принадлежать только одному объекту в один момент времени. Если другой объект хочет получить мьютекс, который уже принадлежит кому-то, он должен ждать, пока мьютекс не будет освобожден. В ядре FreeBSD мьютексы принадлежат процессам.

Мьютексы могут быть получены рекурсивно, но предполагается, что они удерживаются в течение короткого периода времени. В частности, нельзя переходить в режим сна, удерживая мьютекс. Если необходимо удерживать блокировку во время сна, используйте блокировку man:lockmgr[9].

Каждый мьютекс обладает несколькими важными свойствами:

Имя переменной::
Имя переменной struct mtx в исходном коде ядра.

Логическое имя::
Имя мьютекса, назначенное ему с помощью `mtx_init`. Это имя отображается в сообщениях трассировки KTR, ошибках и предупреждениях witness, а также используется для различения мьютексов в коде witness.

Тип::
Тип мьютекса в терминах флагов `MTX_*`. Значение каждого флага связано с его значением, как описано в man:mutex[9].

`MTX_DEF`:::
Мьютекс блокировки с ожиданием

`MTX_SPIN`:::
Мьютекс с вращающейся блокировкой (spin mutex)

`MTX_RECURSE`:::
Этот мьютекс допускает рекурсию.

Защищаемые системы::
Список структур данных или членов структур данных, которые защищает эта запись. Для членов структур данных имя будет указано в формате `имя структуры`.`имя члена`.

Зависимые функции::
Функции, которые могут быть вызваны только при удержании этого мьютекса.

.Список мьютексов
[cols="15%,10%,10%,55%,20%", frame="all", options="header"]
|===
| Имя переменной
| Логическое имя
| Тип
| Защищаемые системы
| Зависимые функции

|sched_lock
|"sched lock"
|`MTX_SPIN` \| `MTX_RECURSE`
|`_gmonparam`, `cnt.v_swtch`, `cp_time`, `curpriority`, `mtx`.`mtx_blocked`, `mtx`.`mtx_contested`, `proc`.`p_procq`, `proc`.`p_slpq`, `proc`.`p_sflag`, `proc`.`p_stat`, `proc`.`p_estcpu`, `proc`.`p_cpticks` `proc`.`p_pctcpu`, `proc`.`p_wchan`, `proc`.`p_wmesg`, `proc`.`p_swtime`, `proc`.`p_slptime`, `proc`.`p_runtime`, `proc`.`p_uu`, `proc`.`p_su`, `proc`.`p_iu`, `proc`.`p_uticks`, `proc`.`p_sticks`, `proc`.`p_iticks`, `proc`.`p_oncpu`, `proc`.`p_lastcpu`, `proc`.`p_rqindex`, `proc`.`p_heldmtx`, `proc`.`p_blocked`, `proc`.`p_mtxname`, `proc`.`p_contested`, `proc`.`p_priority`, `proc`.`p_usrpri`, `proc`.`p_nativepri`, `proc`.`p_nice`, `proc`.`p_rtprio`, `pscnt`, `slpque`, `itqueuebits`, `itqueues`, `rtqueuebits`, `rtqueues`, `queuebits`, `queues`, `idqueuebits`, `idqueues`, `switchtime`, `switchticks`
|`setrunqueue`, `remrunqueue`, `mi_switch`, `chooseproc`, `schedclock`, `resetpriority`, `updatepri`, `maybe_resched`, `cpu_switch`, `cpu_throw`, `need_resched`, `resched_wanted`, `clear_resched`, `aston`, `astoff`, `astpending`, `calcru`, `proc_compare`

|vm86pcb_lock
|"vm86pcb lock"
|`MTX_DEF`
|`vm86pcb`
|`vm86_bioscall`

|Giant
|"Giant"
|`MTX_DEF` \| `MTX_RECURSE`
|почти всё
|много

|callout_lock
|"callout lock"
|`MTX_SPIN` \| `MTX_RECURSE`
|`callfree`, `callwheel`, `nextsoftcheck`, `proc`.`p_itcallout`, `proc`.`p_slpcallout`, `softticks`, `ticks`
| 
|===

[[locking-sx]]
== Разделяемые эксклюзивные блокировки

Эти блокировки обеспечивают базовую функциональность типа читатель-писатель и могут удерживаться спящим процессом. В настоящее время они реализованы через man:lockmgr[9].

.Список разделяемых эксклюзивных блокировок
[cols="20%,80%", options="header"]
|===
| Имя переменной
| Защищаемые системы

|`allproc_lock`
|`allproc` `zombproc` `pidhashtbl` `proc`.`p_list` `proc`.`p_hash` `nextpid`

|`proctree_lock`
|`proc`.`p_children` `proc`.`p_sibling`
|===

[[locking-atomic]]
== Атомарно защищённые переменные

Переменная с атомарной защитой — это специальная переменная, которая не защищена явной блокировкой. Вместо этого все операции доступа к данным этой переменной используют специальные атомарные операции, как описано в man:atomic[9]. Очень немногие переменные обрабатываются таким образом, хотя другие примитивы синхронизации, такие как мьютексы, реализованы с использованием переменных с атомарной защитой.

* `mtx`.`mtx_lock`
