有些时候需要给资源分配一个唯一id(32bit or 64bit or CHAR[N]),这里主要说下分配方法问题。
首先我们有个基本前提,如果是单线程分配,那么我们无需下面的方法,直接++value即可(CHAR型无论几线程都可使用GUID)顺序产生不重复序列,下面讨论的方法都是多线程下的分配策略:
方法1、 win下做简单的方法莫过于使用InterlocckedIncrement(or InterlockedIncrement64)了,这个调用也很简单,每次递增一个,多线程间保证顺序递增绝无重复。此方法只可在单一进程上使用。
方法2、区间法,每个线程一次申请一个id区间[m, n],用完了再申请下一个区段,申请的时候锁一次,其他时间都不用锁,效率比3略低,比1高。此方法也只可在一个进程上使用,当然如果申请的策略修改一下也可实现多个进程甚至不同机器上的进程之间独立分配id。
方法3、方法1虽然简单但毕竟InterlockedXXX系列函数调用还是有些耗时的,大概50cpu周期级别,更简单的方法可以使用线程切分原理,如有3个线程参与id分配,我们这样分配:
线程1 base=1, step =3,序列1,4,7,10,…
线程2 base=2, step=3,序列2,5,8,11,…
线程3 base=3, step=3,序列3,6,9,12,…
绝无重复,调用非常简单每个线程id = base; base += step;即可。
此方法在单进程上使用很简单,如果要拓展到多个进程上使用要通过配置来实现,但也是不难的。
方法4、如果id可用GUID表示那么方法要简单一点,生成id直接调用guid生成算法,这个id生成算法即使在多个进程之间甚至不同机器之间也可以保证唯一,也有其价值。