memcached 网络模型

2022-04-13 00:00:00 函数 线程 响应 步骤 箭头

多线程

memcached包含一个main线程,和若干个worker子线程。main线程负责监听创建客户端连接。worker线程负责处理各个客户端的请求。



memcached启动时,main线程创建了一个listen_fd负责监听端口,worker线程监听管道状态。

(1)一旦有客户端连接(图中蓝箭头1),Event_handler响应函数触发

(2)event_handler会向某一个worker线程的管道写数据(箭头2),这会触发线程的管道响应函数thread_libevent_process。

(3) thread_libevent_process函数会接受client_fd, 放入其线程队列中,并设置其对应的事件函数eventhandler(箭头3)。

(4)客户端发送set,get等命令(箭头4),event_handler函数被触发,调用具体命令的处理方法。

(5)处理后,返回结果(箭头5)



一个比喻:

main线程就类似于10086的接线员,worker线程是具体的业务员。用户拨打10086(步骤1),接线员(main)通知具体的业务员(步骤2),业务员接起电话(步骤3),接下来的步骤,用户可以和业务员直通,步骤4和步骤5





伪代码的调用关系图如下:


main(){

    xxx_init()   一系列初始化函数



    memcached_thread_init(){

        for each thread(){

            setup_thread() {

                event_set(notify,)   // 响应函数 thread_libevent_process

                cq_init()

                cache_create()

            }

            create_worker(){

                new thread with func worker_libevent() {

                    event_base_loop()   // 每个线程进入循环

                }

            }

        }        

    }

    init_lru_crawler()

    clock_handler()


    server_sockets(){

        server_socket(){

            bind()

            listen()

            conn_new(){    // accept是面向多客户端的,需要放到event里处理

                event_set()   // 连接事件,响应函数 event_handler

            }


            

        }

    }


    event_base_loop()

}



event_handler(){  //主线程和worker线程响应函数

    drive_machine(){

        case: new_listening

        dispatch_conn_new(){

                notify worker thread;

                push CQ_ITEM to queue;


        }


        case 

    }

}


thread_libevent_process(){  // 管道fd的响应函数


    switch(){

        case c 新连接

            conn_new() { event_set()}


            conn_worker_readd(){

                event_set()

            }



        case p 


        case t 


        case s

    }



}





上述代码,注意conn函数的特点,在main和worker中都有被调用, 给main和worker注册事件响应函数。

来源 https://www.modb.pro/db/103311

相关文章