- 主题:各位精英码农,来出出主意
一个很繁忙的系统中,10K-20K 用户,每个用户每隔一段时间比如(30秒,或者60秒)需要自动把自己状态改变为另外一个状态,误差不能大于2-3秒。
现在两个方案:
1. 每个用户一个 asio timer, 定时触发后检测时间,如果到了时间后,就改变状态
2. 单独用一个线程对这些用户定时遍历检测时间,然后改变转台
3. 对这些用户分组,一组一个 asio t imer,比如1000个用户一组。
感觉第三个方案嘴合适?
--
FROM 218.76.62.*
非精英,瞎参和一下。这个要求好像比游戏服务器里刷新一个地图里所有怪的状态低一些
chatgpt把你的第三种称为sharding 。
但它给出了第四种:
最推荐的实际方案(方案 2 + 优化):
方案 4(综合优化):使用最小堆 + 单线程定时扫描
也叫 “定时轮” 或 “时间驱动调度器” 模型。
实现思路:
用一个线程维护一个最小堆(或 std::multimap<time_point, user*>);
每次取堆顶的用户(最近要更新状态的人);
用 sleep_until(堆顶时间) 等待;
到时间后唤醒,批量处理所有时间小于等于当前时间的用户;
然后再次 sleep,进入下一个循环。
好处:
每次唤醒只处理 即将触发 的用户;
实际触发时间 非常接近理论时间点(通常误差 < 1s);
几乎无资源浪费,仅维护一个线程;
可扩展到几十万用户(百万也可以);
减少锁争用,线程内串行操作堆即可。
--
修改:z16166 FROM 123.115.134.*
FROM 123.115.134.*
这个时间是不是固定的?如果是固定的,那一开始排好队列不就完了,轮流做
【 在 speedboy2998 的大作中提到: 】
: 一个很繁忙的系统中,10K-20K 用户,每个用户每隔一段时间比如(30秒,或者60秒)需要自动把自己状态改变为另外一个状态,误差不能大于2-3秒。
: 现在两个方案:
: 1. 每个用户一个 asio timer, 定时触发后检测时间,如果到了时间后,就改变状态
: ...................
--
FROM 182.85.140.*
主贴没有说得很清楚,这些用户时刻都在被其他很多线程用读锁查询他们的状态,不能长时间锁定。
我最终采取的方案是单独一个线程用读写锁。
用读锁遍历,需要更改状态的时候就升级为写锁。。
【 在 z16166 的大作中提到: 】
: 非精英,瞎参和一下。这个要求好像比游戏服务器里刷新一个地图里所有怪的状态低一些
: chatgpt把你的第三种称为sharding 。
: 但它给出了第四种:
: ...................
--
FROM 218.76.62.*
用户又不多,大不了copy一份userlist存uid/timeout/status专门拿来跑定时任务,上锁只需要同步状态的时候对单个用户上锁就行了
【 在 speedboy2998 的大作中提到: 】
: 主贴没有说得很清楚,这些用户时刻都在被其他很多线程用读锁查询他们的状态,不能长时间锁定。
: 我最终采取的方案是单独一个线程用读写锁。
: 用读锁遍历,需要更改状态的时候就升级为写锁。。
: ...................
--
FROM 111.198.57.*