我在a StackOverflow answer中找到了compareAndSwap
的代码:
boolean CompareAndSwapPointer(volatile * void * ptr,
void * new_value,
void * old_value) {
#if defined(_MSC_VER)
if (InterlockedCompareExchange(ptr, new_value, old_value) == old_value) return false;
else return true;
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
return __sync_bool_compare_and_swap(ptr, old_value, new_value);
#else
# error No implementation
#endif
}
这是使用便携式快速代码的最合适方式吗(除了程序集内联)。
另外,一个问题是那些特定的builtin
方法具有不同的参数并且从一个编译器返回另一个编译器的值,这可能需要一些额外的更改,例如本例中的if then else
。
另一个问题是机器代码级别中这些builtin
方法的行为,它们的行为是否完全相同? (例如使用相同的装配说明)
注意:另一个问题是,如果此示例中有许多受支持的平台(Windows
和Linux
)。代码可能会变得很大。
答案 0 :(得分:3)
我会使用硬件抽象层(HAL),它允许通用代码通用 - 并且可以为每个平台包含和构建任何可移植源。
在我看来,这允许更好的结构化和更可读的来源。
为了让您更好地了解此过程,我建议Google查找示例和解释。
希望这个简短的回答有所帮助。
[编辑]我将尝试一个Bionix的简单示例,以展示如何实现HAL系统......
mrAMainApplication.c包含以下内容......
#include "hal.h"
// This gets called every time around the main loop ...
void mainProcessLoop( void )
{
unsigned char key = 0;
// scan key ...
key = hal_ReadKey();
if ( key != 0 )
{
hal_PrintChar( key );
}
}
然后他创建了一个头文件(记住 - 这是一个例子,不是工作代码!)......
他创造了hal.h ......
#ifndef _HAL_H_
#define _HAL_H_
unsigned char hal_ReadKey( void );
unsigned char hal_PrintChar( unsigned char pKey );
#endif // _HAL_H_
现在A先生需要两个单独的源文件,一个用于他的'天河-2'系统和另一个为他的Amiga 500 ...
hal_A500.c
void hal_ReadKey( void )
{
// Amiga related code for reading KEYBOARD
}
void hal_PrintChar( unsigned char pKey )
{
// Amiga related code for printing to a shell...
}
hal_Tianhe2_VERYFAST.c
void hal_ReadKey( void )
{
// Tianhe-2 related code for reading KEYBOARD
}
void hal_PrintChar( unsigned char pKey )
{
// Tianhe-2 related code for printing to a shell...
}
A先生 - 当为Amiga建设时 - 建立mrAmainApplication.c和hal_A500.c 为天河2号建造时 - 他使用hal_Tianhe2_VERYFAST.c而不是hal_A500.c
是的 - 我用一些幽默写了这个例子,这对任何人来说都没有标记,只是我觉得它让这个例子更有趣,并希望有助于理解。
尼尔
答案 1 :(得分:1)
看看ConcurrencyKit,可能你可以使用更高级别的原语,这可能是大多数人真正想要的。与某些操作系统特定的HAL相比,我认为CK适用于Windows以及许多非gcc编译器。
但是如果你只是对如何实施"比较和交换"感兴趣?或者在各种C编译器上可移植的原子操作,查看并查看该代码的工作原理。它都是开源的。
我怀疑细节可能会变得混乱,而且对于普通大众而言,这些细节通常不会为简单或有趣的阐述做出贡献。
答案 2 :(得分:1)
在现代C中,从C11开始,使用_Atomic
作为类型限定,使用atomic_compare_exchange_weak
作为函数。
新版本的gcc和clang符合C11标准,并以便携方式实现这些操作。