Portable Compare And Swap (атомарные операции) Библиотека C / C ++?

Если функция из исходного файла, доступного в файловой системе, может помочь inspect.getsource(foo) :

Если foo определяется как:

def foo(arg1,arg2):         
    #do something with args 
    a = arg1 + arg2         
    return a  

Затем:

import inspect
lines = inspect.getsource(foo)
print(lines)

Возвраты:

def foo(arg1,arg2):         
    #do something with args 
    a = arg1 + arg2         
    return a                

Но я считаю, что если функция скомпилирована из строки, потока или импортирована из скомпилированного файл, то вы не можете получить его исходный код.

29
задан pjhsea 28 June 2012 в 09:57
поделиться

9 ответов

Intel Threading Building Blocks имеет красивый переносимый шаблон atomic<T>, который делает то, что вы хотите. Но может ли это быть небольшая библиотека или нет, конечно, можно обсуждать ..

15
ответ дан Kristian 28 June 2012 в 09:57
поделиться

Вы также можете посмотреть на libsync для вдохновения из http://www.ioremap.net/node/224 , который является довольно новым (возможно, слишком новым), но он используется в Elliptics Сеть, так что она (некоторые?) Тестирование.

Это также дает вам примитивы более высокого уровня рядом с CAS: RCU (Read Copy Update) для синхронизации без блокировки между потоками.

Но это зависит от того, что вы подразумеваете под «портативным»: он поддерживает архитектуры x86 и PPC, ОС Linux, FreeBSD, OpenBSD, Solaris и MacOSX, но ... без Windows.

И лицензия GPL, которую вы можете ненавидеть или любить.

0
ответ дан Rutger Nijlunsing 28 June 2012 в 09:57
поделиться

Автор сказал (по предоставленной вами ссылке): «Я думаю, вы можете безопасно использовать их, пока не появится какая-нибудь официальная библиотека Boost». Откладывать изменение интерфейса до тех пор, пока «атомарные функции не появятся в C ++ 0x».

Что бы вы ни использовали сегодня, вы, вероятно, захотите перейти на новую std:: функциональность, когда она все равно будет доступна.

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

Я бы пошел на это.

2
ответ дан osgx 28 June 2012 в 09:57
поделиться

Возможно, вас заинтересуют функции Атомных операций Глиба ,

g_atomic_int_compare_and_exchange()

реализует семантику CAS для различных архитектур. Сама реализация относительно проста для понимания и может использоваться автономно без особых усилий, вы можете найти ее на svn.gnome.org/viewvc/ в glib / trunk / glib / gatomic. {C, h}. Надеюсь, это поможет!

11
ответ дан llongi 28 June 2012 в 09:57
поделиться

Предложена C ++ 0x-совместимая библиотека атомизации Boost: http://www.chaoticmind.net/~hcb/projects/boost.atomic/

Цель этой библиотеки - предоставить реализацию атомарных операций для повышения, основанную на интерфейсе, заданном проектом стандарта C ++ 0x. Он призван упростить переход на std :: atomic, а также предоставить средства, позволяющие сделать код с использованием этой функции C ++ 0x скомпилированным на старых системах.

Это, очевидно, еще не является частью Boost, но вы можете проверить ветку обзора здесь: http://lists.boost.org/Archives/boost/2009/12/160195.php

Boost.Atomic теперь в форме, которую я считаю называть релизом. Он поддерживает «истинные» атомарные переменные в:

  • gcc / x86, 32-битный (тестируется в Linux, FreeBSD)
  • gcc / x86, 64-битный (тестируется на Linux)
  • gcc / powerpc32 (протестировано на Linux, Mac OS X)
  • gcc / powerpc64 (не проверено)
  • универсальный Win32 (протестировано с Visual Studio Express на Win XP)

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

3
ответ дан Trevor Robinson 28 June 2012 в 09:57
поделиться

Библиотека промежуточных процессов boost может быть тем, что вам нужно, - включающий файл Atomic.hpp содержит реализации сравнения и замены для различных платформ и компиляторов.

25
ответ дан Steve Gilham 28 June 2012 в 09:57
поделиться

OPA (Open Portable Atomics) может подойти для ваших нужд. https://trac.mcs.anl.gov/projects/openpa/

. Он обеспечивает согласованный C API для общих элементарных операций на нескольких платформах под лицензией в стиле MIT. Библиотека небольшая и, безусловно, отвечает вашим требованиям к размеру. Текущий список платформ:

  • Встроенная сборка GCC для процессоров x86, x86_64, ia64, PPC 440 и MIPS 5K. Несколько компиляторов с GCC-совместимым интерфейсом ish также поддерживаются в одной архитектуре, такой как icc, PGI и IBM xlc.
  • Атомные свойства GCC, поэтому поддерживается большинство установок GCC-4.1 +.
  • Библиотека атомных операций SUN Solaris.
  • Встроенные функции Windows NT (хотя в настоящее время вам нужно проделать небольшую дополнительную работу для сборки в Windows).
  • Две псевдоплатформы, эмуляция на основе мьютекса pthread для переносимости на другие неподдерживаемые платформы (при этом жертвуя некоторой производительностью), и «небезопасная» реализация для использования в коде, который условно компилируется в однопоточный код.

Я никогда не использовал его в программе на C ++, хотя он должен работать практически без изменений. Я был бы рад настроить его, если у вас возникнут проблемы (просто напишите opa-discuss@lists.mcs.anl.gov).

30
ответ дан Dave Goodell 28 June 2012 в 09:57
поделиться

Существует библиотека проекта atomic_ops Бёма. Не знаю о лицензии, хотя.

6
ответ дан Dirk 28 June 2012 в 09:57
поделиться

В Mac OS X и Windows есть встроенные функции CompareAndSwap, которые вы должны использовать в любом случае (InterlockedCompareExchange () и OSAtomicCompareAndSwapPtrBarrier () соответственно). Таким образом, будет работать независимо от компиляторов на этих платформах.

В других Unix-системах это немного сложнее, если вы используете GCC 4.1 или новее, вы можете просто использовать его встроенную функцию __sync_val_compare_and_swap (), и многие, хотя и не все компиляторы Unix, поддерживают разумные расширения gcc, так как большая часть кода начинается в Linux предполагается, что они присутствуют.

Поэтому, если вы хотите обернуть их так, чтобы они работали практически со всеми компиляторами для всех процессоров в OS X и Windows, а также с GCC и некоторыми другими компиляторами на других платформах, вам следует сделать что-то вроде:

boolean CompareAndSwapPointer(volatile * void * ptr,
                                  void * new_value,
                                  void * old_value) {
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
  return OSAtomicCompareAndSwapPtr (old_value, new_value, ptr);
#elif defined(_MSC_VER)
  return InterlockedCompareExchange(ptr, new_value, old_value);
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
  return __sync_val_compare_and_swap(ptr, old_value, new_value);
#else
#  error No implementation
#endif
}

Это не проверено, но я думаю, что это должно быть правильно. Обратите внимание, как все библиотеки ОС принимают аргументы в разных порядках; -)

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

9
ответ дан Louis Gerbarg 28 June 2012 в 09:57
поделиться
Другие вопросы по тегам:

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