在 C++ 中生成唯一 ID 的最佳算法是什么?长度 ID 应为 32 位无符号整数。
6 回答
获得一个唯一的 32 位 ID 很简单:下一个。工作 40 亿次。136 年独一无二,如果您需要一秒钟。魔鬼在细节中:前一个是什么?您需要一种可靠的方式来持久保存最后使用的值,并需要一种原子方式来更新它。
这有多难取决于 ID 的范围。如果它是一个进程中的一个线程,那么您只需要一个文件。如果它是一个进程中的多个线程,那么您需要一个文件和一个互斥锁。如果一台机器上有多个进程,那么您需要一个文件和一个命名的互斥锁。如果它是多台机器上的多个进程,那么您需要分配一个权威的 ID 提供者,即所有机器都与之通信的单个服务器。数据库引擎就是这样一个常见的提供者,他们有这个内置的特性,一个自动增量列。
随着范围的扩大,获取 ID 的费用会逐渐增加。当它变得不切实际时,范围是 Internet 或提供商太慢或不可用,那么您需要放弃 32 位值。切换到随机值。随机性足以使机器被流星击中的可能性比重复相同 ID 的可能性至少高一百万倍。一个好ID。它只有 4 倍大。
这是我能想到的最简单的ID。
MyObject obj;
uint32_t id = reinterpret_cast<uint32_t>(&obj);
在任何给定时间,此 ID 在整个应用程序中都是唯一的。没有其他对象将位于同一地址。当然,如果您重新启动应用程序,可能会为该对象分配一个新 ID。一旦对象的生命周期结束,可能会为另一个对象分配相同的 ID。
并且不同内存空间中的对象(例如,在不同的计算机上)可能被分配相同的 ID。
最后但同样重要的是,如果指针大小大于 32 位,则映射将不是唯一的。
但是,由于我们对您想要什么样的 ID 以及它应该有多独特一无所知,所以这似乎是一个很好的答案。
DWORD uid = ::GetTickCount();
::Sleep(100);
几乎没有上下文,但如果您正在为应用程序中的对象寻找唯一 ID,您始终可以使用类似于以下的单例方法
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 ()