Lighttpd 1.5的多线程实现(2)

                continue/* just notifying us that srv->is_shutdown changed */ 

            /* don't care about the return code for now */ 

            stat(sj->name->ptr, &st); 

            joblist_async_append(srv, sj->con); 

            stat_job_free(sj); 

        } 

    } 

    g_async_queue_unref(srv->stat_queue); 

    return NULL; 

在这里,又看到了g_async_queue的身影,g_async_queue_ref函数的作用是在不加锁的情况下,获得对stat_gueue异步队列的引用。在个在线程启动的时候调用,之后,就会进入while循环,这个while循环的条件是!srv->is_shutdown,也就是程序只要不退出,循环一直进行。在循环内部,可以看到一条if判断语句:

if ((sj = g_async_queue_pop(inq))) 

g_async_queue_pop也是线程池的关键,glibc中对这个函数的注释为:

Pops data from the queue. This function blocks until data become available

当异步队列中有可用数据时,将其弹出,否则将一直阻塞在这里。

接下来还要判断从异步队列中取得的数据是否为1,这是因为lighttpd将1设为线程退出的指令,当异步队列中pop出1时,线程就要退出。如果不为1说明是正常的数据(任务),需要处理。处理完成后,继续循环等待新的任务到来。

那又是在哪把任务、消息加入到stat_cache队列中的呢?主要有两个地方,一个是在stat_cache.c中的stat_cache_get_entry_internal()函数内部,调用了g_async_queue_push(srv->stat_queue, sj);将sj推入了stat_queue队列;另一处在server.c的main函数的最后几行,

for (i = 0; i < srv->srvconf.max_stat_threads; i++) { 

            g_async_queue_push(srv->stat_queue, (void *) 1); 

注意,这里向stat_cache队列中加入了多次1,目的通知每个线程,程序即将结束,需要线程退出。

整个脉络现在基本清晰了,也就是lighttpd程序维护了异步消息队列stat_queue,然后启动了几个线程stat_cache_thread,每个线程都在循环等待stat_queue中是否有新加入的数据(任务)。当新的数据(任务)来临时,某一个线程的g_async_queue_pop函数就会返回这个数据的指针,然后线程就将处理这次的任务。处理完成后,stat_cache_thread线程就会运行到g_async_queue_pop函数处,并阻塞在这里,等待下次任务的到来。

Lighttpd 的详细介绍请点这里
Lighttpd 的下载地址请点这里

相关阅读

CentOS 5.6 下搭建Lighttpd

Cacti监控Lighttpd

Ubuntu 手动编译安��Lighttpd配置运行PHP

移植Lighttpd Web服务器到ARM Linux系统

Ubuntu下搭建Lighttpd+PHP+MySQL环境

在CentOS 5.6 上安装 Lighttpd + PHP5 + MySQL

Lighttpd 对视频文件压缩文件做防盗链

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwzsgw.html