若谈论技术, 那就陷入细节了
不过我可以给你分析一下里面需要解决的问题
1. 你不可能用 channel 简单实现的了
你可以假设一个数据库字段自增操作, 之所以假设数据库, 是因为这是一个昂贵操作。
以下假设都是基于我面临的问题, 所以不用怀疑我下面描述的合理性, 只管接受这些假设及要求即可。
现在有若干个比如 1000 个协程每个都对该字段 +1 并返回自增后的数字, 因为这是一个昂贵操作, 因此现在要求其中只允许一个协程代理全部的操作, 对其 +1000。
剩下的只需要获得操作的结果 N,
然后这 1000 个协程通过合适的逻辑, 分别返回 [N - 999, N] 之间的一个数字, 以保证返回结果和他亲自调用 +1 并返回自增后的结果一样。
这里的要求是在操作过程中, 仍然会时不时有新的协程对这个字段做 +1 操作, 但必须等+1000 结束后才能进行;
那么等 +1000 结束, 可能有 2 群协程, 一群是 +1000 后拿到结果直接返回的, 另一群是 +1000 结束后, 对字段继续 +1 的;
然后还有要求, 第一群需要同时唤醒, 以尽量降低调度延迟; 第二群里面的需要只唤醒一个, 让其代理对第二群里面的所有自增操作; 自然第一群那些唤醒后分行李的协程不能阻塞第二群被唤醒的那个协程
当然, 这里面没有保证这一群必须是 1000 或某个固定数字, 因为有可能再也没有 +1 的协程到来了, 第二群唤醒的那个协程必须保证只代理它在检查第二群那一瞬间看到的那些 +1, 后继的组成第三群, 不能代理
你用 channel 实现试试, 或者除了别用我的办法, 你用你能想到的任何办法试试, 我也好奇还有没有更优实现。
2. 这里面没有 bug, 你若认为有明显竞态, 说明你没有看懂
: 简单一个,SwapPointer不和LoadPointer配对使用就会带来问题
你甚至都没有看到 LoadPointer 在哪里, 或者你没有意识到另一个swap pointer 操作的目标根本没有要读的必要, 简单说, 就是 lock 返回值会告诉caller 是进入了临界区还是单纯分行李, 分行李的不需要 unlock.
unlock 定义的语意是 只要当前锁确实是上锁的, 则解锁, 并不是只有持有锁的才能解锁,golang mutex.unlock 同样是这个表现。 里面的swap pointer 只是为了保证如果已经解锁了, 则不做任何事。
你可以将你的理解及认为的解决方案说出来, 或者将你认为的 nr 有问题到底怎么有问题说出来
【 在 MyWorkLife 的大作中提到: 】
: 不评价你的遭遇
: 但是代码里面问题不少
: 最大的问题是思维方式
: ...................
--
修改:zylthinking2 FROM 223.104.3.*
FROM 220.181.41.*