futex(7) | Miscellaneous Information Manual | 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.
ПРИМЕЧАНИЯ
Ещё раз повторим: в чистом виде фьютексы не являются лёгкой в использовании абстракцией для конечных пользователей. Использующие их программисты должны иметь хороший запас знаний об ассемблере и уметь читать исходный код библиотеки фьютексов для пользовательского пространства, указанной далее.
В этой справочной странице показано самое распространённое использование примитивов futex(2), которое ни в коем случае не единственное.
СМОТРИТЕ ТАКЖЕ
clone(2), futex(2), get_robust_list(2), set_robust_list(2), set_tid_address(2), pthreads(7)
Fuss, Futexes and Furwocks: Fast Userlevel Locking in Linux (proceedings of the Ottawa Linux Symposium 2002), futex example library, futex-*.tar.bz2 https://mirrors.kernel.org/pub/linux/kernel/people/rusty/.
ПЕРЕВОД
Русский перевод этой страницы руководства разработал 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 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику по его адресу электронной почты или по адресу списка рассылки русских переводчиков.
2 мая 2024 г. | Linux man-pages 6.8 |