On The Road
圣光之下,先知说: 不要写程序; 写小程序; 别把程序写大。
C++博客
首页
新随笔
联系
聚合
管理
随笔 - 82 文章 - 171 trackbacks - 0
<
2008年9月
>
日
一
二
三
四
五
六
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(3)
给我留言
查看公开留言
查看私人留言
随笔分类
《GAME PROGRAMMING GEMS6》读书笔记(4)
《UNIX编程艺术》读书笔记(4)
垃圾收集(3)
随笔档案
2008年11月 (1)
2008年10月 (3)
2008年9月 (11)
2008年7月 (2)
2008年6月 (1)
2008年5月 (2)
2008年4月 (1)
2008年3月 (1)
2008年1月 (1)
2007年11月 (5)
2007年10月 (1)
2007年9月 (2)
2007年8月 (1)
2007年7月 (2)
2007年6月 (1)
2007年5月 (2)
2007年3月 (1)
2007年2月 (2)
2007年1月 (2)
2006年12月 (5)
2006年10月 (6)
2006年9月 (4)
2006年8月 (8)
2006年7月 (6)
2006年6月 (6)
2006年5月 (5)
技术
梦想风暴
千里马肝
叶的BLOG
云风
朋友
Innocence Space
搜索
积分与排名
积分 - 75590
排名 - 23
最新评论
1. re: 崩溃后重启,用共享内存恢复你的数据
评论内容较长,点击标题查看
--imdavid
2. re: 崩溃后重启,用共享内存恢复你的数据
可以用保护线程
把崩溃的信息记录下来,顺便把未保存的数据保存下
--饭中淹
3. re: 崩溃后重启,用共享内存恢复你的数据
mapping file爆快,其中一个优点。
--陈梓瀚(vczh)
4. re: 崩溃后重启,用共享内存恢复你的数据
共享一个文件写入性能实在很低,而且弄得操作系统的IO频繁,
文章提出的方案的确有意思,JAVA有外部的缓冲实现,这个貌似等同的
不同之处在于共享内存和Socket访问的区别
--Jeason Zhao
5. re: 崩溃后重启,用共享内存恢复你的数据
@肥仔
你可以试一下写文件的,呵呵
我没试过
--LOGOS
阅读排行榜
1. 乱谈CEGUI(2244)
2. 如何在游戏机制中使用AI/剧情脚本----基于LUA(2131)
3. 聊内存池技术(1901)
4. 单元测试PPT讲义(1882)
5. 读《修改代码的艺术》(1801)
评论排行榜
1. 通用网络消息包(12)
2. 滥用assert(10)
3. 谈谈不一样的singleton(9)
4. wxWidget的HelloWorld(8)
5. IPC,读《Unix编程艺术》某章感(8)
60天内阅读排行
1. 崩溃后重启,用共享内存恢复你的数据(1252)
2. 高效调用lua函数(1240)
3. lmock 0.4 release(1035)
4. 垃圾收集的那点事(K)(985)
5. 垃圾收集的那点事(J)(975)
垃圾收集的那点事(F)
接着昨天的cache_flush,首先进入以此开头的这个代码块
if
(children)
{
while
(j
<
children
->
number)
{
这个代码块主要是处理一些取消内存关系的cache节点,并预估需要重新分配的children大小。这里有一个先决条件是,cache是按child_id升序排序的,同样children也是升序排序的。
if
(child
==
(children
->
children[j]
|
UNSET_MASK))
{
--
k;
head
->
parent
=-
1
;
--
sz;
++
head;
}
从上面可以看出,如果是取消内存关系的cache节点,之前统计的cache节点数量sz就要减一。估计有些人会纳闷为什么还要减一,毕竟当初统计节点数量的时候,就没有把UNSET_MASK的cache节点算进去。这是因为sz的作用并不是用来表示节点的数量,而是表示children需要拓展的尺寸,由于标记UNSET_MASK的child要从children中删除,那么children数组中就有空闲的位置,所以需要拓展的尺寸也就减少,sz就减一了。
再看
if
(head
>=
next)
{
goto
copy_next;
}
如果cache中的所有节点都是UNSET_MASK的话,就会跳到copy_next处,移动children的其他部分来填充被删除的那些child_id。copy_next的代码我就不贴了。
else
if
((child
&
~
UNSET_MASK)
<
children
->
children[j])
{
break
;
}
如果进入这个判断,则说明cache中不全是UNSET_MASK节点,还包含添加新关系的节点存在。虽然这个判断不直观,但是鉴于他们都是升序排序的,这样的判断也就行得通了。
进入下面的代码,就是利用上面计算出来的sz拓展children的时候了。
if
(sz
>
0
)
{
children
=
node
->
u.n.children
=
link_expand(node
->
u.n.children,sz);
assert(children);
memmove(children
->
children
+
j
+
sz, children
->
children
+
j , (children
->
number
-
j)
*
sizeof
(
int
));
j
+=
sz;
}
其中的
link_expand
就是拓展数组的地方,里面的实现基本上就是realloc,策略不同而已。
拓展之后,用移动内存的方式,在children数组中留个空缺,容纳还没有处理的cache节点。空缺要留得足够大,搞不好剩下的cache节点都是添加的。
接下来有再进入一个代码块
while
(j
<
children
->
number)
{
这个while循环和上面讲述的有点像,不过其任务不再是计算需要拓展的空间。
第1个if,仍旧是从children中删除关系的。但是第2个if,则不再是一个break了
else
if
((child
&
~
UNSET_MASK)
<
children
->
children[j])
{
assert(child
>=
0
);
children
->
children[k]
=
child;
head
->
parent
=-
1
;
++
head;
--
j;
}
新添加的child_id,放到刚才拓展children时腾出来的空间中去,并保持children升序排序,这一点很重要。
剩下的代码就没什么了,就是复制child_id到children中,无论child_id来自children还是cache,总之要保证他们升序排序。
看起来,cache_flush是看完了。但是仍旧觉得这个函数无比烂,有太多的地方,需要用人类有限的处理能力去进行分析和维护。
明天,是应该看看之前那些暂时略过不看的代码了。到这里为止,只是跟着程序一条分支看看而已,还有其他分支呢。
posted on 2008-09-16 21:41
LOGOS
阅读(1034)
评论(0)
编辑
收藏
引用
标题
姓名
主页
验证码
*
内容(提交失败后,可以通过“恢复上次提交”恢复刚刚提交的内容)
Remember Me?
登录
使用高级评论
新用户注册
返回页首
恢复上次提交
[使用Ctrl+Enter键可以直接提交]
相关链接:
网站导航:
博客园
BlogJava
博客生活
IT博客网
C++博客
PHP博客
博客园社区
管理博客
教师博客
天文博客
汽车博客
足球博客
股票博客
电子博客
管理