Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用于生成唯一Id的函数局部静态变量_C++_C_Thread Safety - Fatal编程技术网

C++ 用于生成唯一Id的函数局部静态变量

C++ 用于生成唯一Id的函数局部静态变量,c++,c,thread-safety,C++,C,Thread Safety,可能重复: 下面的函数是否每次调用时都返回一个唯一的数字?在多线程场景中呢 int returnUniqueNumber() { static int i = 0; ++i; return i; } 这取决于您的平台,因为您将遇到多线程问题。在windows上,您最好执行以下操作: int returnUniqueNumber() { volatile static long l = 0; return (int)InterlockedIncrement( &l

可能重复:

下面的函数是否每次调用时都返回一个唯一的数字?在多线程场景中呢

int returnUniqueNumber()
{
  static int i = 0;
  ++i;
  return i;
}

这取决于您的平台,因为您将遇到多线程问题。在windows上,您最好执行以下操作:

int returnUniqueNumber()
{
  volatile static long l = 0;
  return (int)InterlockedIncrement( &l );
}

这些函数保证是原子的。

以下是Goz关于windows的回答,对于Linux/GCC,请参见此问题/回答:


在这种情况下,您需要
\uuu sync\u add\u and_fetch()

如果您的应用程序是单线程的,那么您发布的代码实际上是生成唯一数字的正确的、符合标准的C/C++方法。但是,由于您正在寻找线程安全解决方案,因此必须深入研究特定于平台的解决方案。Goz有一个很好的Windows解决方案。Mac OS X或iOS上的一个等价物是:

int returnUniqueNumber_APPLE(void) {
    static volatile int32_t i = 0;
    return (int)OSAtomicIncrement32Barrier(&i);
}
在使用最新的ish GCC编译的任何系统上,都有GCC的内部函数:

int returnUniqueNumber_GCC(void) {
    static volatile int i = 0;
    return __sync_add_and_fetch(&i, 1);
}

您不应该将
静态int*
强制转换为
易失性long*
——相反,在这两种情况下,它都应该是(适当限定的)
long*
,并在返回时(或仅由函数隐式地)强制转换为
int
long
int
(以及Windows'
long
typedef)它们的大小并不总是一样的,虽然这种石膏在窗户上可能很好,但它会助长坏习惯。:)@乔纳森:明白了,修正了。我向你致敬,先生+1代表您,1代表简单准确的代码!在int的最大值达到之后,然后是-ve值,它不是旋转回0,1,2@是的。它将计数到2^31-1,然后它将交换到-2^31并计数到0。循环无限延续。这是twos补码编码的主要优点…看起来我们已经介绍了Windows、Linux和MacOS:)不仅仅是Linux,还有大多数*NIXes.)事实上,我们几乎涵盖了所有主要的现代系统。Android可能是剩下的唯一一个,在那里,您可以在函数的返回类型之前抛出一个
synchronized
关键字,然后就可以完成了。(Java有正确的原子操作吗?我不是说
AtomicInteger
等等)