Look under the start memcahced threading process
memcached multi-threaded mainly by instantiating multiple libevent, are a main thread and n workers thread is the main thread or workers thread all through the the libevent management network event, in fact, each thread is a separate libevent instance
The main thread is responsible for monitoring the client to establish a connection request and accept connections
workers thread to handle events such as read and write has established good connections
Look at general icon:
First look main data structures (thread.c):
CQ_ITEM is actually the main thread accept returned package to establish a connection fd
CQ is a CQ_ITEM the singly linked list
Memcached thread structure package, you can see each thread contains a CQ queue, a notification pipe pipe
The instance event_base and a libevent
Another important structure is the most important for each network connection Package conn
memcached mainly through Settings / conversion connected to different states to handle the event (core function drive_machine)
See next thread initialization process:
The main function of the memcached.c, first initialized on the main thread libevent
Then initialize all workers thread and start the startup process will be described in detail later
Then the main thread calls (only analyze the the tcp situation, memcached support udp)
This method encapsulates create listening socket bound address, set the non-blocking mode and register the listening socket
the libevent read event, a series of operations
Then the main thread calls
At this time the main thread start libevent to accept the the external connection request, the entire start-up process is completed
Let's look at how to start thread_init all workers thread, look at the core code thread_init
threads statement
static LIBEVENT_THREAD * threads;
The thread_init first malloc thread space, and then the first threads as the main thread, the rest are workers thread is then created for each thread a pipe, this pipe is used as the main thread to inform the workers thread a new connection arrives
Following setup_thread for
the create setup_thread libevent instance of all workers thread (the libevent main thread instance has been established in the main function)
Since the threads before [0] base = main_base; first thread (the main thread) will not be here execution event_init ()
In this method, then is to register all workers thread pipe read end the libevent of read events, wait for the main thread last all workers CQ initialization
the create_worker actually is the real start of the thread pthread_create call worker_libevent method, this method is executed
event_base_loop start the thread libevent
Here we need to remember that each workers thread only data from the read end of the pipe in its own thread readable trigger, and call
thread_libevent_process methods
Look at this function
The fd function parameters pipe read end of the thread descriptor first 1 byte of the pipeline notification signal readout (this is necessary in the level trigger mode, if does not handle the event, it will be loop notification know the event to be treated)
the cq_peek from the thread CQ queue take the head of the queue a CQ_ITEM, this CQ_ITEM is thrown into the main thread in the queue, item-> SFD is already established connection descriptor, by conn_new function of the descriptor registration the libevent read event, me-> Base on behalf of a thread structure, that is the descriptor event processing the to this workersThreading, the most important elements of conn_new method is:
You can see the new connection is registered to an event (actually EV_READ | EV_PERSIST), processed by the current thread (because event_base here the workers thread)
When the connection readable data callback event_handler function, actually event_handler in the main call memcached core method drive_machine of
Finally, look at the main thread is how to notify workers thread to handle the new connection, the main thread libevent registered readable event listening socket descriptor word, that is, when to establish a connection request, the main thread will handle the callback function is also the event_handler readable event (in fact, the main thread is initialized by conn_new listening socket libevent)
Last look at the most central part of the memcached network event processing - drive_machine
Need to keep in mind is drive_machine perform multi-threaded environment, the main thread and the workers will executive drive_machine,
First of all, less than in fact be the while loop misleading (most do java students will immediately think of a cycle of the loop) while usually to meet a
will break in the case, while taking into account the vertical trigger mode, you must read the error of EWOULDBLOCK
Closer to home, drive_machine mainly by the current connection state to determine the what, by to libevent registered callback after the read and write time are the core function, so we registered libevent event, while the event state is written to the conn structure libevent callback will the conn structure as an argument over the method parameter
the memcached connected through an enum declaration
Actual for case conn_listening: This is the main thread to deal with their own Workers threads never do this branch we see the main thread to accept calls
dispatch_conn_new (sfd, conn_read, EV_READ | EV_PERSIST, DATA_BUFFER_SIZE, false);
This function is to inform workers thread to see
You can clearly see, the main thread first create a new CQ_ITEM, then select a thread through the round robin strategy
And cq_push this CQ_ITEM into the thread CQ queue, the corresponding workers thread is how do you know it
Is through this
write (threads [thread]. notify_send_fd, "", 1)
Write 1-byte data to this thread pipe, then the thread's the libevent immediate callback the thread_libevent_process method (already described above)
Then the thread remove the item, Register read time, when the data connection of that section will eventually callback drive_machine method, that is,
method case conn_read drive_machine: all workers deal with the main thread only processing conn_listening establish a connection to this
This part of the code is indeed more, can not all posted, please refer to the source code, the latest version 1.2.6, the province went to a lot of optimization such as, each CQ_ITEM is malloc will malloc a lot to reduce debris generation and so the details.
reference from:http://www.cprogramdevelop.com/408519/