#c #generics #atomic
Вопрос:
Этот вопрос касается только stdatomic.h.
Скажем, мне нужен какой-то механизм, который позволяет мне создавать атомарные «каналы» с любыми данными, включая пользовательские struct
. Я представляю себе что-то вроде:
struct chan {
atomic_intptr_t ptr;
};
Идея состоит в том, чтобы иметь _Atomic intptr_t
возможность хранить ссылки буквально на любые данные.
Тогда давайте представим, что у меня есть пользовательские данные…
struct person {
char * name;
};
…и я публикую это на своем атомном канале:
struct person bob = {
.name = "Bob"
};
struct person alice = {
.name = "Alice"
};
struct chan c = {
.ptr = amp;bob
};
Учитывая это, следующий код является одним из многих способов, которыми я мог бы передавать новые данные на свой канал:
atomic_exchange(amp;c.ptr, amp;alice);
Это работает, но gcc
предупреждает меня:
предупреждение: инициализация ‘atomic_intptr_t’ {aka ‘long int’} из ‘struct person *’ делает целое число из указателя без приведения [-Wint-преобразование]
Поэтому мне кажется, что я выбрал неправильный подход.
Каков лучший способ иметь универсальный канал, способный атомарно обмениваться любыми данными? Можете _Generic
ли вы помочь здесь?
Комментарии:
1. @selbie Я не занимаюсь C , если вы имеете в виду атомарный шаблон.
2. @SerejaBogolubov — Ой, ты прав. Моя вина!
Ответ №1:
Указатели также могут быть объявлены _Atomic
, поэтому я думаю, что вам здесь нужно просто void *
атомарное значение. (Возможно, вас вводит в заблуждение отсутствие удобного определения типа для этого, но оно отлично работает, и атомарные указатели не блокируются на большинстве распространенных платформ.) Таким образом:
#include <stdatomic.h>
struct chan {
void * _Atomic ptr;
} c;
struct person {
char * name;
} alice;
int some_integer = 8;
void add_some_stuff(void) {
atomic_exchange(amp;c.ptr, amp;alice);
// ...
atomic_exchange(amp;c.ptr, amp;some_integer);
// ...
atomic_exchange(amp;c.ptr, NULL);
}
Комментарии:
1. Я не знал, что это работает и с необработанным указателем. Хотя в этом есть смысл. Спасибо!