mt.h(3)

📦
version 2.2.0 · 2 versions
, in fedora 44

🌸 NAME 🌸

mt.h — Поддержка многозадачности 🧵✨

Окей бести, слушай сюда 💅 Это заголовочный файл из Library Functions Manual, раздел 3, и он весь про то, как куча потоков тусит внутри одной программы и не устраивает тотальный хаос. Мьютексы, атомарные счётчики, вызов функции ровно один раз, сон на миллисекунды — вот это всё 🫶 Держись, тут всё разложено по полочкам, no cap.


✨ SYNOPSIS ✨

#include 'bee2/defs.h'

🎀 Определения типов 🎀

  • typedef bool_t mt_mtx_t — Мьютекс. Да, вот прям так, вот это и есть тип мьютекса 💖

🦋 Функции 🦋

  • bool_t mtMtxCreate (mt_mtx_t *mtx) — Создание мьютекса: рождаем его с нуля ✨
  • bool_t mtMtxIsValid (const mt_mtx_t *mtx) — Корректный мьютекс? Типа вайб-чек для мьютекса 🔍
  • void mtMtxLock (mt_mtx_t *mtx) — Блокировка мьютекса: забираем его себе 🔒
  • void mtMtxUnlock (mt_mtx_t *mtx) — Разблокировка мьютекса: отпускаем на свободу 🕊
  • void mtMtxClose (mt_mtx_t *mtx) — Закрытие мьютекса: говорим ему пока-пока 👋
  • void mtSleep (u32 ms) — Приостановка потока: заслуженный чилл 😴
  • bool_t mtCallOnce (size_t *once, void(*fn)()) — Вызов один раз: буквально один раз, periodt 1️⃣
  • size_t mtAtomicIncr (size_t *ctr) — Атомарный инкремент: счётчик плюс один, без гонок ⚡
  • size_t mtAtomicDecr (size_t *ctr) — Атомарный декремент: счётчик минус один, тоже без гонок ⚡
  • size_t mtAtomicCmpSwap (size_t *ctr, size_t cmp, size_t swap) — Атомарное сравнение с заменой: сверили и подменили 🔥

📖 Подробное описание 📖

Вот тут начинается самое вкусное, бести 🍓

Предусловие

Все входные указатели действительны, если не оговорено противное. Это база: не подсовывай мусорные указатели, пожалуйста 🙈

🔒 Мьютексы 🔒

Мьютекс — это объект, который может находиться ровно в одном из двух состояний: "заблокирован" или "разблокирован". Всё, никаких промежуточных вайбов, только эти два.

Поток блокирует мьютекс с помощью функций mtMtxLock(), mtMtxTryLock() и снимает блокировку с помощью функции mtMtxUnlock(). И вот тут слушай внимательно, это важно: заблокировать можно только разблокированный мьютекс. Поэтому вызов mtMtxLock() повлечёт приостановку выполнения потока вплоть до разблокировки мьютекса. То есть поток реально сидит и ждёт своей очереди, как в очереди за матчей ☕

С помощью мьютексов можно синхронизировать доступ к общим объектам потоков. Перед доступом к объекту каждый из потоков должен заблокировать мьютекс, а после операции над объектом — разблокировать его. Схема буквально: зашёл, взял, сделал, отпустил 👑

Управление мьютексами реализуется по схемам, заданным в стандарте языка Си ISO/IEC 9899:2011 (см. заголовочный файл threads.h).

Интерфейс мьютексов упрощён по сравнению со стандартом: ошибки при блокировке и разблокировке мьютекса не предполагаются. То есть этот интерфейс даже не рассматривает вариант, что что-то может пойти не так 🙈

Если операционная система не распознана, то мьютексы будут "положительно пустыми": они всегда будут успешно создаваться, блокироваться и разблокироваться, хотя за этими действиями не будет стоять никакого функционала. Красиво же: всё как будто работает, а на самом деле — ничего 💀

Прим.

В реализации для Windows используются облегчённые мьютексы — так называемые критические секции (critical sections). Да, у Windows свой отдельный вайб ✨

🧵 Управление потоками 🧵

Управление потоками реализуется по схемам, заданным в стандарте языка Си ISO/IEC 9899:2011 (см. заголовочный файл threads.h). Тот же стандарт, тот же заголовок, тот же вайб 🫶

⚛️ Элементарные атомарные операции ⚛️

Операции выполняются над счётчиками типа size_t, представленными указателями. Операции атомарны в том смысле, что счётчик защищён от изменения в других потоках вплоть до завершения операции. Никаких гонок, всё чётко, highkey 💅

Предупреждения

Если указатель на счётчик не выровнен на границу size_t, то поведение функций может быть непредсказуемым. 💀 Просто не делай так, окей?

🛠 Функции 🛠

size_t mtAtomicCmpSwap (size_t * ctr, size_t cmp, size_t swap)

Счётчик ctr атомарно сравнивается с cmp и, в случае совпадения, устанавливается равным swap. Ну то есть: "если там ровно то, что я жду — меняем на вот это" ✨

Возвращает

Первоначальное значение счётчика.

Аргументы

  • ctr — счётчик
  • cmp — сравниваемое значение
  • swap — новое значение

size_t mtAtomicDecr (size_t * ctr)

Счётчик ctr атомарно уменьшается на 1. Минус единичка, и всё это без гонок ⚡

Прим.

Возможно переполнение (снизу, undeflow). Да-да, вниз тоже можно улететь 🙈

Возвращает

Новое значение счётчика.

Аргументы

  • ctr — счётчик

size_t mtAtomicIncr (size_t * ctr)

Счётчик ctr атомарно увеличивается на 1. Плюс единичка, тоже атомарно ⚡

Прим.

Возможно переполнение (сверху, overflow).

Возвращает

Новое значение счётчика.

Аргументы

  • ctr — счётчик

bool_t mtCallOnce (size_t * once, void(* fn )())

Функция fn() вызывается в точности один раз даже в ситуации конкурентных запросов на вызов из разных потоков. Для контроля однократности вызова используется триггер once, первоначально нулевой. Это буквально "сделай один раз и хватит", даже если десять потоков одновременно кричат "я первый!" 🎀

Ожидается

Триггер once инициализируется нулём и не меняется за пределами функции.

Возвращает

TRUE, если fn() успешно вызвана в данном или предыдущем обращении к mtCallOnce(), и FALSE в противном случае.

Аргументы

  • once — триггер
  • fn — функция

void mtMtxClose (mt_mtx_t * mtx)

Мьютекс mtx закрывается. Всё, пока-пока, было круто 👋

Предусловие

Мьютекс корректен и не заблокирован.

mtMtxClose() < mtMtxCreate().

Прим.

Закрытие заблокированного мьютекса может привести к непредсказуемым последствиям. Это не "ой, ну ладно, проехали", это реально плохая идея 💀

Аргументы

  • mtx — мьютекс

bool_t mtMtxCreate (mt_mtx_t * mtx)

Создаётся мьютекс mtx. Рождение мьютекса, легенда ✨

Возвращает

Признак успеха.

Постусловие

В случае успеха мьютекс корректен.

Аргументы

  • mtx — мьютекс

bool_t mtMtxIsValid (const mt_mtx_t * mtx)

Проверяется корректность мьютекса mtx. Типа чекаем, всё ли с ним ок, или он уже не тот 🔍

Возвращает

Признак корректности.

Аргументы

  • mtx — мьютекс

void mtMtxLock (mt_mtx_t * mtx)

Мьютекс mtx блокируется.

Предусловие

Мьютекс корректен.

Прим.

Если мьютекс заблокирован в момент вызова, то ожидается снятие блокировки (в другом потоке). Так что поток просто ждёт, бести, ждёт ☕

Аргументы

  • mtx — мьютекс

void mtMtxUnlock (mt_mtx_t * mtx)

Мьютекс mtx разблокируется. Свобода! 🕊

Предусловие

mtMtxUnlock() < mtMtxLock().

Мьютекс корректен.

Аргументы

  • mtx — мьютекс

void mtSleep (u32 ms)

Текущий поток приостанавливается на ms миллисекунд. Заслуженный чилл 😴

Прим.

1 секунда = 10^3 миллисекунд = 10^6 микросекунд = 10^9 наносекунд.

Если операционная система не распознана или операционная система не поддерживает многозадачность, то приостановки не будет. Хочешь поспать — а сна нет. Кринж 💀

Аргументы

  • ms — число миллисекунд

✍️ Автор ✍️

Автоматически создано Doxygen для Библиотека Bee2 из исходного текста. Доксиген сделал всю работу, ему респект 🤖💖


Ну всё, бести, это была страничка mt.h(3) из Библиотеки Bee2, сгенерённая Вс 25 Янв 2026 00:00:00 🦋 Обнимаю, целую, и, пожалуйста, не забывай разблокировать свои мьютексы 🫶💖

📦 where this page comes from