原子操作一直是多线程编程中的重要杀器之一。Win32里我们有Interlocked系列API,其他平台下也有各自的原子操作接口。如果想要让我们的程序能够拥有跨平台且统一的多线程调度方案,那么就必须得把不同的操作接口统一(C++11中已经有了跨平台的原子操作接口,不过当不方便使用C++11的时候,自己简单的写一套还是有一定需要的)。
首先,我们需要定义一套平台判断宏,来方便我们决定使用何种接口:
#if defined(WINCE) || defined(_WIN32_WCE)
# define NX_OS_WINCE
#elif defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
# define NX_OS_WIN64
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
# define NX_OS_WIN32
#elif defined(__linux__) || defined(__linux)
# define NX_OS_LINUX
#else
# error "This OS is unsupported"
#endif
#if defined(NX_OS_WIN32) || defined(NX_OS_WIN64) || defined(NX_OS_WINCE)
# define NX_OS_WIN
#else
# define NX_OS_UNIX
#endif
考虑到编译的差异(gcc下提供了一套跨平台的原子操作接口),编译器也需要区分开:
#if defined(_MSC_VER)
# if (_MSC_VER <= 1200)
# define NX_CC_MSVC6
# endif
# define NX_CC_MSVC
#elif defined(__GNUC__)
# define NX_CC_GNUC
#else
# error "This CC is unsupported"
#endif
这里我们就只简单的考虑Windows、Linux,以及VC、gcc之间的区分。下面,我们需要定义跨平台的接口兼容层:
namespace atomic
{
#if defined(NX_OS_WIN32) || defined(NX_OS_WINCE)
typedef volatile LONG type_t;
typedef LONG norm_t;
#elif defined(NX_OS_WIN64)
typedef volatile LONG64 type_t;
typedef LONG64 norm_t;
#else
typedef volatile long type_t;
typedef long norm_t;
#endif
}
//
#if defined(NX_CC_GNUC)
# define nx_atomic_inc(var) __sync_fetch_