Вопрос по atomic, c, posix, concurrency – UNIX Portable Atomic Operations

28

Есть ли в C (POSIX-) переносимый способ для операций с атомарными переменными, аналогичный переносимому потоку с pthread?

Атомарные операции - это такие операции, как "increment and get" которые выполняются атомарно, это означает, что никакой переключатель контекста не может вмешиваться в операцию. В пространстве ядра Linux мы должныatomic_t типа, в Java у нас естьjava.util.concurrent.atomic пакет.

В Linux файл atomic.h обеспечивает атомарные операции, но включение зависит от платформы, например#include <asm-x86_64/atomic.h> и он не доступен в Mac OS X аналогичным образом.

а вот для более нового gcc:gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html osgx
Хорошо, ограничено GCC, но это было бы хорошо для меня. dmeister
Есть некоторые встроенные функции GCC,described here. caf

Ваш Ответ

7   ответов
4

any портативные без блокировки / атомные операции. Вот почему у них есть нитки.

Вы или должны будете использовать нестандартные способы или использовать ptrheads для переносимости.

1

C11 atomics minimal runnable example

С добавлением потоков в glibc 2.28 мы можем выполнять как атомарность, так и создание потоков в чистом C11.

Пример из:https://en.cppreference.com/w/c/language/atomic

main.c

#include <stdio.h>
#include <threads.h>
#include <stdatomic.h>

atomic_int acnt;
int cnt;

int f(void* thr_data)
{
    for(int n = 0; n < 1000; ++n) {
        ++cnt;
        ++acnt;
        // for this example, relaxed memory order is sufficient, e.g.
        // atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed);
    }
    return 0;
}

int main(void)
{
    thrd_t thr[10];
    for(int n = 0; n < 10; ++n)
        thrd_create(&thr[n], f, NULL);
    for(int n = 0; n < 10; ++n)
        thrd_join(thr[n], NULL);

    printf("The atomic counter is %u\n", acnt);
    printf("The non-atomic counter is %u\n", cnt);
}

Скомпилируйте и запустите:

gcc -std=c11 main.c -pthread
./a.out

Возможный вывод:

The atomic counter is 10000
The non-atomic counter is 8644

Неатомарный счетчик, скорее всего, будет меньше атомного из-за быстрого доступа через потоки к неатомарной переменной.

Пример pthreads можно найти по адресу:Как мне начать темы в простом C?

Протестировано в Ubuntu 18.04 (glibc 2.27) путем компиляции glibc из исходного кода:Несколько библиотек glibc на одном хосте

0

AFAIK нет кроссплатформенных способов делать атомарные операции. Там может быть библиотека, но я не знаю. Хотя это не так сложно, чтобы кататься самостоятельно.

9

Начиная с C11 есть дополнительныйАтомная библиотека который обеспечивает атомные операции. Это переносимо на любую платформу с компилятором C11 (например, gcc-4.9) с этой дополнительной функцией.

Наличие атома можно проверить с помощью__STDC_NO_ATOMICS__и наличие<stdatomic.h>

atomic.c

#include <stdio.h>
#include <stdlib.h>
#ifndef __STDC_NO_ATOMICS__
#include <stdatomic.h>
#endif

int main(int argc, char**argv) {
    _Atomic int a;
    atomic_init(&a, 42);
    atomic_store(&a, 5);
    int b = atomic_load(&a);
    printf("b = %i\n", b);

    return EXIT_SUCCESS;
}

Compiler invocations

clang -std=c11 atomic.c
gcc -std=c11 atomic.c
0

Я не думаю, что есть.

Одним из способов ее решения, разумеется, разрешением лицензий, было бы копирование соответствующих реализаций для каждой архитектуры, например, из пространство ядра Linux. Я не следил за эволюцией этих примитивов близко, но я бы предположил, что они действительно являются примитивами, то есть не зависят от других сервисов или API в ядре.

10

Так как вы попросили OS X:

(и так как кросс-платформенность была поднята в этой теме.)

OS X имеет функцииOSAtomicAdd32() и друзья. Они объявлены в /usr/include/libkern/OSAtomic.h" ;. УвидетьРуководство по программированию потоков, раздел & quot; Использование атомарных операций & quot ;.

А для Windows естьInterlockedIncrement() и друзья (см. MSDN).

Вместе с gcc buildins__sync_fetch_and_add() и друзья (было связано выше), вы должны иметь что-то для каждой основной настольной платформы.

Обратите внимание, что я еще не использовал их самостоятельно, но, возможно, сделаю это в ближайшие дни.

13

Для любого, кто сталкивается с этим в будущем, атомные атомы C11 - лучший способ сделать это сейчас - я думаю, они будут включены в GCC 4.9.

Можете ли вы расширить это?
Пример минимальной работоспособности C11 Atomics + Threads:stackoverflow.com/questions/1130018/…

Похожие вопросы