其实应用场景是实现一个coc中的选择战斗力相近的用户来pvp的逻辑细节,只是存储假定必须是ets,因为这篇帖子讨论的是ets,ets本身没有提供CAS的原子操作。如果Redis之类的本身就支持CAS的就是另一种做法。
实际的情况是读多写少,这若干行有两种状态A和B,需要从状态属性为A的行中筛选一个,这时候需要读多个,然后对筛选后的1个进行更新操作,将其置为B。因此读多写少。
在筛选和更新这两个操作之间也不是原子操作,因此甚至是状态集合里的成员在被筛选的时候都已经有可能被其他进程更新为状态B了,
问题是在于同一时间有可能多个客户端都选中了同一行,但更新操作必须只能被做一次,之后尝试更新的需要能会返回错误。
当然是需要尽可能的利用多核,因为一个erlang进程最多只能占用一个cpu,所以猜想一下开(cpu核数+1)个服务进程来做`读取+更新`操作比较合适。
这样实际的读取+更新操作就被服务进程串行化了,保证了逻辑的正确,也可以更好的并行,利用cpu核数。
考虑到筛选的行有可能状态已经被改变了,我可以多选几个发给服务进程,它尝试成功更新一个就返回即可,减少一点由于发生冲突,而需要重新筛选计算的可能。
至于数据更新变换函数,其实只是判断一下状态是否是期望的状态,如果是则更新,不是则返回错误,标准的CAS操作。
=======
@Lihe: 因为做erlang没什么经验,大多是纯想法,需要实际的模拟测试才知道是不是靠谱,我是成都的开发者,erlang不是很活跃,只有在论坛上求帮助。