在C++中生成唯一ID的最佳算法是什么? ID长度应为32位无符号整数。
在C++中生成唯一ID的最佳算法是什么? ID长度应为32位无符号整数。
获取一个独特的32位ID很直观简单:下一个。可以工作40亿次。如果每秒需要一个,则136年内唯一。关键在于细节:上一个是什么?您需要一种可靠的方式来保存上次使用的值,并以原子方式更新它。
难度取决于ID的范围。如果只是一个进程中的一个线程,则只需要一个文件。如果是一个进程中的多个线程,则需要一个文件和互斥锁。如果是一个机器上的多个进程,则需要一个文件和命名互斥锁。如果是多个机器上的多个进程,则需要分配一个权威的ID提供者,一个所有机器都与之通信的单个服务器。数据库引擎常常充当这样的提供者,他们将其内置为特性,称为自动递增列。
随着范围的扩大,获取ID的成本逐渐增加。当范围变得不切实际时,如Internet或提供者速度太慢或不可用,则需要放弃32位值。转而使用随机值。足够随机,使得机器被流星击中的可能性至少比重复相同ID的可能性高一百万倍。一个好的ID。大小只是它的四倍。
这是我能想到的最简单的ID。
MyObject obj;
uint32_t id = reinterpret_cast<uint32_t>(&obj);
在任何时候,此ID将在整个应用程序中是唯一的。没有其他对象会位于相同的地址。当然,如果重新启动应用程序,则可能会为对象分配新的ID。当对象的生命周期结束后,可能会分配相同的ID给另一个对象。
不同内存空间中(例如,在不同计算机上)的对象可能会被分配相同的ID。
最后但并非最不重要的是,如果指针大小大于32位,则映射将不是唯一的。
但由于我们不知道您想要什么类型的ID以及它应该有多独特,因此这似乎是一个与其他任何答案一样好的答案。
DWORD uid = ::GetTickCount();
::Sleep(100);
虽然上下文很少,但如果您正在寻找应用程序内对象的唯一标识符,则可以始终使用类似于单例的方法。
class IDGenerator {
public:
static IDGenerator * instance ();
uint32_t next () { return _id++; }
private:
IDGenerator () : _id(0) {}
static IDGenerator * only_copy;
uint32_t _id;
}
IDGenerator *
IDGenerator::instance () {
if (!only_copy) {
only_copy = new IDGenerator();
}
return only_copy;
}
现在您可以随时通过执行以下操作获取唯一的ID:
IDGenerator::instance()->next ()