futex(7)

НАИМЕНОВАНИЕ
futex - быстрая блокировка в пользовательском пространстве

ОБЗОР
#include <linux/futex.h>

ОПИСАНИЕ
Ядро Linux предоставляет фьютексы (futexes, «быстрые мьютексы (mutexes, взаимоисключающие блокировки) в пользовательском пространстве») в качестве строительного блока для быстрой блокировки в пользовательском пространстве и семафоров. Фьютексы очень просты и полезны для создания высокоуровневых абстракций блокировок, таких как мьютексы, условных переменных, блокировок чтения-записи, барьеров и семафоров.

Большинство программистов, фактически, не используют фьютексы напрямую, а полагаются на системные библиотеки, которые на них построены, такие как Native POSIX Thread Library (NPTL) (смотрите pthreads(7)).

Фьютекс отождествляется с участком памяти, который может быть общим для процессов или нитей. В этих процессах фьютекс может быть доступен по разным адресам. В своей основе фьютекс имеет семантику семафора; это счётчик, который можно увеличивать и уменьшать атомарно; процессы могут ждать пока значение не станет положительным.

Работа с фьютексом выполняется полностью в пользовательском пространстве при отсутствии конфликта (noncontended case). Ядро привлекается только для разрешения конфликтов. Так как все проектные решения стремятся к отсутствию конфликтов, фьютексы также оптимизированы под эту ситуацию.

В своей основе фьютекс — это целое число, которое изменяется только атомарными инструкциями ассемблера. Это целое число размером 4 байта на всех платформах. Процессы могут совместно использовать это число посредством mmap(2), сегментов общей памяти или общего пространства памяти (share memory space, в этом случае приложение, обычно, называют многонитевым).

  Поведение
Любое действие с фьютексом начинается в пользовательском пространстве, но может потребовать обращения к ядру через системный вызов futex(2).

Для «установки» фьютекса выполняются соответствующие ассемблерные инструкции, которые заставляют ЦП машины атомарно увеличить целое число. Далее проверяется, было ли действительно изменено значение с 0 на 1, то есть не было ожидающих и операция выполнена. Это бесконфликтный вариант, выполняется быстро и должен возникать чаще всего.

При возникновении конфликта, атомарное увеличение изменяет счётчик с -1 (или другого отрицательного числа). Это означает, что есть ожидающие. В пользовательском пространстве теперь нужно присвоить счётчику 1 и дать команду ядру пробудить всех ожидающих с помощью операции FUTEX_WAKE.

Ожидание фьютекса, его «сброс», является обратной операцией. Происходит атомарное уменьшение счётчика и проверка того, стал ли он равен 0, то есть операция выполнена и фьютекс был неконфликтным. Во всех других случаях, процесс должен присвоить счётчику -1 и запросить ядро об ожидании другого процесса, устанавливающего фьютекс. Это выполняется с помощью операции FUTEX_WAIT.

В системном вызове futex(2) можно указать время ожидания, то есть как долго ядро должно ждать установку фьютекса, В этом случае семантика более сложна и программисту нужно обратиться к futex(2). Это тоже самое что и ожидания асинхронного фьютекса.

ВЕРСИИ
Впервые поддержка фьютексов появилась в Linux 2.5.7, но с другой семантикой. Текущая семантика используется в Linux с версии 2.5.40.

ПРИМЕЧАНИЯ
To reiterate, bare futexes are not intended as an easy-to-use abstraction for end users. Implementors are expected to be assembly-literate and to have read the sources of the futex user-space library referenced below.

This manual page illustrates the most common use of the futex(2) primitives; it is by no means the only one.

СМОТРИТЕ ТАКЖЕ
clone(2), futex(2), get_robust_list(2), set_robust_list(2), set_tid_address(2), pthreads(7)

Fuss, Futexes and Furwocks: Быстрая блокировка на уровне пользователя в Linux (материалы Ottawa Linux Symposium 2002), библиотека примеров фьютексов, futex-*.tar.bz2 https://mirrors.kernel.org/pub/linux/kernel/people/.

ПЕРЕВОД
Русский перевод этой страницы руководства разработал(и) Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков (<debian-l10n-russian@lists.debian.org>).