注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[网游设计] 利用 fork 来定期保存数据  

2010-08-06 17:31:02|  分类: 网游设计 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
基本思想
游戏中,我们希望将某一时刻的玩家数据,一次保存起来,保证没有数据复制。
要把数据保存起来,如果前期设计不好,可能需要到很多模块去抠抠挖挖,把数据序列化好,然后写到磁盘。这个序列化的过程可能就需要花费不少的cpu time。

怎么办呢?如果内存够大(上64-bit system),我们可以先 fork,让parent process继续服务玩家,而 child process 则序列化、写磁盘。利用操作系统来给我们做数据的 snapshot。

实现细节
用 fork,有几个要注意的地方,如下:

signal(SIGCHLD, SIG_IGN);
否则 child process 退出后,会产生 zombie process。但要注意,SIG_IGN会影响一些函数的行为,比如:用了 SIG_IGN system() 必然返回 -1(因为 waitpid 失败)

child process 只会有一个 thread (parent process 调用 fork 的那个 thread),其他的 thread 都自动没了。

child process 不要做任何逻辑,只做存盘的事情就好。

资料参考,看 Steven 老大的 APUE
ch08 Process Control  ==>  8.3 fork Function
ch10 Signals ==> 10.7 SIGCLD Semantics
ch12 Thread Control  ==>  12.9 Threads and fork

ps. FreeBSD上,不处理 signal(SIGCHLD, SIG_IGN),还可以 rfork(RFFDG | RFPROC | RFNOWAIT),通过 RFNOWAIT 把 child process 与 parent 脱钩。参见ps3

ps2. fork进程大量写数据的同时,如果主进程也做了一些io操作,很可能导致主进程block io。

ps3. 厄,rfork() 的行为和 fork() 除了 RFNOWAIT 还是有一些不一样的。rfork() 出来的进程,会保留所有的 thread,而不是仅保留 mainthread。
--------------------------------------------------
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

void *mythread(void *_)
{
        sleep(100);
        return (void *)0;
}

int main()
{
        int pid;
        pthread_t tid;
        pthread_create(&tid, NULL, mythread, NULL);

        pid = fork();
        if ( pid > 0 )
        {
                printf("child = %d\n", pid);
                sleep(100);
        }
        else if ( pid == 0 )
        {
                sleep(100);
        }

        return 0;
}
--------------------------------------------------
通过 kill -SIGABRT pid 把 child process coredump,通过 gdb 来看。
#0  0x28171c2f in nanosleep () from /lib/libc.so.7        # rfork()
[New Thread 28217140 (LWP 100128)]
[New Thread 28201140 (LWP 100125)]
[New LWP 100108]

#0  0x28171c2f in nanosleep () from /lib/libc.so.7        # fork()
[New Thread 28201140 (LWP 100079)]
--------------------------------------------------
所有 thread 保留,意味着有可能有出错,小心、谨慎。rfork() 比较危险,不熟悉不要用。

  评论这张
 
阅读(682)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017