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

Atomic Operations — основные атомарные операции с целочисленными и указателями

Краткое описание

#include <glib.h> gint g_atomic_int_get (volatile gint *atomic); void g_atomic_int_set (volatile gint *atomic, gint newval); void g_atomic_int_add (volatile gint *atomic, gint val); gint g_atomic_int_exchange_and_add (volatile gint *atomic, gint val); gboolean g_atomic_int_compare_and_exchange (volatile gint *atomic, gint oldval, gint newval); gpointer g_atomic_pointer_get (volatile gpointer *atomic); void g_atomic_pointer_set (volatile gpointer *atomic, gpointer newval); gboolean g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic, gpointer oldval, gpointer newval); void g_atomic_int_inc (gint *atomic); gboolean g_atomic_int_dec_and_test (gint *atomic);

Описание

Следующие функции могут использоваться для атомарного доступа к целочисленным и указателям. Иначе они реализуются как действующие ассемблерные функции на большинстве платформ и используют медленный переход в аварийный режим (fall-backs). Их использование может иногда уберечь вас от использования расточительной работы GMutex для защиты целочисленных и указателей.

Самое важное использование - это подсчёт ссылок. Используя g_atomic_int_inc() и g_atomic_int_dec_and_test() выполняется очень быстрая операция подсчёта ссылок.

Примечание

Вы не должны непосредственно читать целочисленные или указатели с одновременным многопоточным доступом, а использовать вместо этого функции атомарного доступа. Таким образом, всегда используйте g_atomic_int_get() и g_atomic_pointer_get() для чтения извне. Они обеспечивают необходимый механизм синхронизации как границы памяти для одновременного обращения к распределённой памяти.

Примечание

Если вы используете эти функции для чего то кроме простого подсчета ссылок, вы должны знать реальную реализацию этого. Существует буквально тысячи способов навредить себе. Поэтому если вы сомневаетесь, используйте GMutex. Если вы не знаете что такое границы памяти не используйте ничего кроме g_atomic_int_inc() и g_atomic_int_dec_and_test().

Примечание

Не безопасно устанавливать целочисленное или указатель простым назначением, когда к ним параллельно обращаются другие нити (threads) со следующими функциями. Используйте g_atomic_int_compare_and_exchange() или g_atomic_pointer_compare_and_exchange() соответственно.

Детали

g_atomic_int_get ()

gint g_atomic_int_get (volatile gint *atomic);

Читает значение целочисленного на которое указывает atomic. Также действует как граница памяти.

atomic : указатель на целочисленное
Возвращает : значение *atomic

Начиная с версии 2.4


g_atomic_int_set ()

void g_atomic_int_set (volatile gint *atomic, gint newval);

Устанавливает значение целочисленного указанного atomic. Также действует как граница памяти.

atomic : указатель на целочисленное
newval : новое значение

Начиная с версии 2.10


g_atomic_int_add ()

void g_atomic_int_add (volatile gint *atomic, gint val);

Атомарно добавляет val к целочисленному указанному atomic. Также действует как граница памяти.

atomic : указатель на целочисленное.
val : значение добавляемое к *atomic.

Начиная с версии 2.4


g_atomic_int_exchange_and_add ()

gint g_atomic_int_exchange_and_add (volatile gint *atomic, gint val);

Атомарно добавляет val к целочисленному указанному atomic. Возвращает значение *atomic непосредственно перед добавлением. Также действует как граница памяти.

atomic : указатель на целочисленное.
val : значение добавляемое к *atomic.
Возвращает : значение *atomic перед добавлением.

Начиная с версии 2.4


g_atomic_int_compare_and_exchange ()

gboolean g_atomic_int_compare_and_exchange (volatile gint *atomic, gint oldval, gint newval);

Сравнивает oldval с целочисленным указанным atomic и если они равны, атомарно обменивает *atomic с newval. Также действует как граница памяти.

atomic : указатель на целочисленное.
oldval : принятое старое значение *atomic.
newval : новое значение *atomic.
Возвращает : TRUE, если *atomic был равен oldval. Иначе FALSE.

Начиная с версии 2.4


g_atomic_pointer_get ()

gpointer g_atomic_pointer_get (volatile gpointer *atomic);

Читает значение указателя на который указывает atomic. Также действует как граница памяти.

atomic : указатель на gpointer.
Возвращает : значение добавляемое к *atomic.

Начиная с версии 2.4


g_atomic_pointer_set ()

void g_atomic_pointer_set (volatile gpointer *atomic, gpointer newval);

Устанавливает значение указателя на который указывает atomic. Также действует как граница памяти.

atomic : указатель на gpointer
newval : новое значение

Начиная с версии 2.10


g_atomic_pointer_compare_and_exchange ()

gboolean g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic, gpointer oldval, gpointer newval);

Сравнивает oldval с указателем на который указывает atomic и если они равны, атомарно обменивает *atomic с newval. Также действует как граница памяти.

atomic : указатель на gpointer.
oldval : принятое старое значение *atomic.
newval : новое значение *atomic.
Возвращает : TRUE, если *atomic был равен oldval. Иначе FALSE.

Начиная с версии 2.4


g_atomic_int_inc ()

void g_atomic_int_inc (gint *atomic);

Атомарно увеличивает указатель на который указывает atomic на 1.

atomic : указатель на целочисленное.

Начиная с версии 2.4


g_atomic_int_dec_and_test ()

gboolean g_atomic_int_dec_and_test (gint *atomic);

Атомарно уменьшает указатель на который указывает atomic на 1.

atomic : указатель на целочисленное.
Возвращает : TRUE, если целочисленное на которое указывает atomic после уменьшения равно 0.

Начиная с версии 2.4

Смотрите также

GMutex

GLib взаимные исключения.