【发布时间】:2009-11-17 15:42:13
【问题描述】:
我正在使用静态库;它有一个使用当前时间并创建一个唯一 ID 的函数,然后将其插入我的数据库中。这个数字在我的数据库表中应该是唯一的。
有两个进程并行运行。有时他们同时调用这个函数,并生成相同的数字。发生这种情况时,我会违反完整性。
我正在考虑使用进程 ID、线程 ID 和当前时间。这种组合是独一无二的吗?
平台:Windows XP
【问题讨论】:
标签: c++ windows multithreading
我正在使用静态库;它有一个使用当前时间并创建一个唯一 ID 的函数,然后将其插入我的数据库中。这个数字在我的数据库表中应该是唯一的。
有两个进程并行运行。有时他们同时调用这个函数,并生成相同的数字。发生这种情况时,我会违反完整性。
我正在考虑使用进程 ID、线程 ID 和当前时间。这种组合是独一无二的吗?
平台:Windows XP
【问题讨论】:
标签: c++ windows multithreading
使用数据库来生成它们。如何做到这一点取决于数据库,但 Postgres 将它们称为序列作为示例。
【讨论】:
如果程序同时运行,则进程/线程 ID 将是唯一的,因为操作系统需要区分它们。但是系统确实重用了 id。 因此,对于您的情况,是的,将进程 ID 或线程 ID 添加到您的标记中是一个好主意,但我认为您不需要两者。
【讨论】:
在 Windows 上,线程 ID 在整个系统中是唯一的。请参阅此 MSDN 库文章:
http://msdn.microsoft.com/en-us/library/ms686746%28v=VS.85%29.aspx
CreateThread 和 CreateRemoteThread 函数还返回一个标识符,用于唯一标识整个系统中的线程。线程可以使用 GetCurrentThreadId 函数来获取自己的线程标识符。从线程创建到线程终止,标识符都是有效的。请注意,没有线程标识符永远是 0。
【讨论】:
很遗憾,进程 ID、线程 ID 和时间的组合不能保证是唯一的。一旦它们引用的线程和进程终止,操作系统可能会重用进程 ID 和线程 ID。此外,用户可以将时钟调回,因此同一时间出现两次。正如其他人所说,我会要求数据库提供一个唯一的 ID。 Oracle有序列,MySQL有自增列,其他数据库有类似机制。
【讨论】:
虽然进程 ID 和线程 ID 将是唯一的,但最好使用数据库为您生成唯一 ID(正如 R. Pate 建议的那样),因为这可能会限制您的可伸缩性,除非您还包含唯一的机器 ID...
虽然您在机器 A 上运行的一个进程可能与在机器 B 上运行的一个进程具有相同的进程 ID 和线程 ID,但这些错误总是会导致人们起床的错误类型。凌晨 4 点处理支持电话...
【讨论】:
好吧,添加进程ID和线程ID可能会导致相同的数字
pid= 100,tid= 104 pid= 108, tid= 96
不太可能,但可能。
因此,对于近乎安全的 ID,您至少需要一个 64 位 ID 字段,例如
ULONG64 id = ((ULONG64)(pid&0xffff) << 48) | ((ULONG64)(tid&0xffff) << 32) | (timestamp & 0xffffffff);
(但是,这仍然不能保证唯一性,因为它假设线程 ID 不会与进程 ID 重叠,它们会抵消 16 位值,但我认为我从未见过超过 65536 的 PID,除非您正在创建数千个线程,在时间戳跳转之前线程 ID 不会在此值中回绕)。
【讨论】: