Apache内存池内幕(7)[3]

[入库:2006年2月23日] [更新:2007年3月24日]

本文简介:

    apr_kill_conditions_e kill_how;
    /** The next process in the list */
    struct process_chain *next;
};
对于内存池p,任何一个进程如果需要从p中分配对应的描述数据结构apr_proc_t,那么它首先必须维持一个process_chain结构,用于描述当p被销毁的时候,如何处理该进程。Process_chain的成员很简单,proc是进程描述,kill_how是销毁处理策略,如果存在多个进程都从p中分配内存,那么这些进程的process_chain通过next形成链表。反过来说,process_chain链表中描述了所有的从当前内存池中分配apr_proc_t结构的进程的销毁策略。正因为进程结构的特殊性,因此如果某个程序中需要使用进程结构的话,那么第一件必须考虑的事情就是进程的退出的时候处理策略,并将其保存在subprocess链表中,该过程通过函数apr_pool_note_subprocess完成:
APR_DECLARE(void) apr_pool_note_subprocess(apr_pool_t *pool, apr_proc_t *proc,
                                           apr_kill_conditions_e how)
{
    struct process_chain *pc = apr_palloc(pool, sizeof(struct process_chain));
    pc->proc = proc;
    pc->kill_how = how;
    pc->next = pool->subprocesses;
    pool->subprocesses = pc;
}
apr_pool_note_subproces的实现非常简单,无非就是对process_chain的成员进行赋值,并插入到subprocess链表的首部。
比如,在URI重写模块中,需要将客户端请求的URI更改为新的URI,如果使用map文件进行映射的话,那么根据请求的URI到map文件中查找新的URI的过程并不是由主进程完成的,相反而是由主进程生成子进程,然后由子进程完成的,下面是精简过的代码:
static apr_status_t rewritemap_program_child(…)
{
    ……
    apr_proc_t *procnew;
    procnew = apr_pcalloc(p, sizeof(*procnew));
    rc = apr_proc_create(procnew, argv[0], (const char **)argv, NULL,procattr, p);
    if (rc == APR_SUCCESS) {
            apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT);
            ……
    }
    ……
}
从上面的例子中可以看出,即使描述结构被删除,子进程也必须3秒后才被中止,不过3秒已经足够完成查询操作了。
同样的例子可以在下面的几个地方查找到:Ssl_engine_pphrase.c文件的577行、Mod_mime_magic.c文件的2164行、mod_ext_filter.c文件的478行、Log.c的258行、Mod_cgi.c的465行等等。
现在我们来考虑内存池被销毁的时候处理进程的情况,所有的处理由free_proc_chain完成,该函数通常仅仅由apr_pool_clear或者apr_pool_destroy调用,函数仅仅需要一个参数,就是process_chain链表,整个处理框架就是遍历process_chain链表,并根据处理策略处理对应的进程,描述如下:
static void free_proc_chain(struct process_chain *procs)
{
    struct process_chain *pc;
    if (!procs)

本文关键:Apache内存池内幕(7)
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top