« 使用 closure 替代 table | 返回首页 | type redefinition 的解决方法 »

资源的管理及加解锁

周末我们遇到一个问题。运行时的资源需要统一的管理,资源本身是用垃圾回收的方法管理的。但是,有时候资源需要 lock 住,发生 gc 的时候绝对不能清理掉。我们最初的想法是,把加栽的资源 lock 的时候挂到一个 lock 链上,unlock 的时候取下来。

但是资源这个东西经常被重复使用,而我们又没有引用记数,导致 unlock 的操作无法正确工作。

最容易想到的解决的方法是给对象加上引用计数,但是直觉告诉我,肯定有方法避免。因为使用 gc ,原本就想避免繁琐的加减引用的过程。还需要给资源接口添加引用控制的方法,(我们的设计里,基类是没有引用控制的方法的)而且不是每个对象都需要保存引用计数这个变量。如果引用计数不放在对象上,就只能放在链表节点上,我们还需要提供一个资源对象映射到 lock 链表节点的途径。显然,去使用一个代价昂贵的 map 非常的傻。

最后使用的解决方案是这样的:

使用一个指针数组,每次 lock 或 unlock 一个资源对象指针的时候,直接把地址压进数组里。当然,因为是指针,我们可以用一个比较 trick 的方法区分是 lock 还是 unlock 。那就是 unlock 的时候把地址加一。因为一般对象地址都是 dword 对齐的。

因为我们可以根据 lock 和 unlock 的次数来知道实际 lock 的对象有多少个,当 lock 次数和 unlock 次数相等的时候,就把数组清空即可。在实际应用中,往往也可以调用 unlock_all 的方法全部清空(通常是在一帧图片渲染完毕后)。

当数组的大小远大于实际被 lock 的对象数量的时候,我们认为数据冗余过多。这个时候对数组先排序,然后可以用一个简单的一次扫描的算法,把对相同地址的 lock 和 unlock 操作合并了。这个整理过程被调用的频率很低,同时也可以快速的完成。

Comments

不错踩一脚路过你这里去别处了
mark!纯沙发

Post a comment

非这个主题相关的留言请到:留言本