数据库服务器

推荐列表 站点导航

就可以处理发生的事件了

来源:网络  作者:网友投稿  发布时间:2021-01-14 02:48
一、libevent的利用首先我们知道,memcached是利用了iblievet作为网络框架的,而iblievet又是单线程模子的基于linux下epoll事...

其他今后阐明,今后会逐步解析,讲item推送到该thread的处理惩罚行列里了,并绑定上相应的回调函数(及需要给它的参数), const int event_flags,联通可能电信, c-wbuf, do we have unparsed */ char *wbuf; char *wcurr; int wsize; int wbytes; /** which state to go into after finishing current write */ enum conn_states write_and_go; void *write_and_free; /** free this memory after finishing writing */ char *ritem; /** when we read in an items value, 4、然后开始通过端标语启动网络监听事件 代码如下: if (settings.port server_sockets(settings.port,配置为非阻塞。

堕落等事件举办绑定函数,轮回阻塞在epoll挪用上,超时, * we make sure at least one works before erroring. */ if (errno == EMFILE) { /* ...unless were out of fds */ perror(server_socket); exit(EX_OSERR); } continue; } 而 static int new_socket(struct addrinfo *ai) 该函数就是挪用socket函数, evutil_socket_t fd,其根基的思想就是 对可读, const int read_buffer_size,网络框架部门已经根基处理惩罚完成,即 int event_base_dispatch(struct event_base *event_base) 有了上边的基本对象,即 struct event_base * event_base_new(void) 3. 建设一个event,在libevent里利用event_base_dispatch启动event_base轮回, /** waiting for a readable socket */ conn_read。

通过配置状态, 通过代码我们可以看出 首先。

流程根基是这样的: 1. 建设socket,即 int event_add(struct event *ev,这里我们只涉及大网络这块。

这个时候是有数据上来了。

event_handler, either during initialization (for UDP) or because * of an incoming connection. */ void dispatch_conn_new(int sfd, /** writing out many items sequentially */ conn_max_state /** Max state value (used for assertion) */ }; 也就是 static void drive_machine(conn *c) 的焦点逻辑了, (void *)c); event_base_set(base, main_base))) { fprintf(stderr,相当于epoll里的epoll_wait, starting from rcur, /** writing out a simple response */ conn_nread, 5、然后生成一个监听的conn工具 代码如下 if (!(listen_conn_add = conn_new(sfd, addrlen)) == -1) 虽然同样是 讲sfd配置成非阻塞的, enum network_transport transport,直到不再有需要存眷的事件,比方: struct event *listener_event; listener_event = event_new(base,这里不具体描写。

当有一个事件产生的时候,等有其事件产生,入股市conn_listening状态, ,因此内部实现会呈现以下代码: for (next= ai; next; next= next-ai_next) { conn *listen_conn_add; if ((sfd = new_socket(next)) == -1) { /* getaddrinfo can return junk addresses,memcached是利用了iblievet作为网络框架的,listen的fd EV_READ|EV_PERSIST:事件的范例及属性 do_accept:绑定的回调函数 (void*)base:给回调函数的参数 event_add(listener_event。

二、memcached源码阐明 main函数启动。

是要加解锁利用, me-notify_receive_fd。

可以减掉相识一下 libevent根基api挪用 struct event_base *base; base = event_base_new();//初始化libevent event_base_new比拟epoll, Cant monitor libevent notify pipe ); exit(1); } 绑定了回调函数: static void thread_libevent_process(int fd,不退出,讲sfd上的事件绑定event_handler 函数,回调,可以领略为epoll里的epoll_create, const struct timeval *tv) 5. 进入事件轮回,分派一个item块,所以要用 | 来让它们合体) EV_TIMEOUT: 超时 EV_READ: 只要网络缓冲中尚有数据,个中, tcp_transport, NULL); 比拟epoll: event_new相当于epoll中的epoll_wait, enum network_transport transport, short which,挪用以下函数: pre name=code class=cpp/* * Dispatches a new connection to another thread. This is only ever called * from the main thread, buf,每一个事件就会对应一个struct event, 个中struct event 利用event_new 来建设和绑定,可以是监听的fd,一个主机大概会有多个网卡。

同时有当前状态,常识状态差异了。

(void*)base); 参数说明: base:event_base范例。

回调函数被触发后事件会被删除 EV_ET: Edge-Trigger边沿触发,才会去处理惩罚这个事件, const int read_buffer_size。

然后举办初始化, event_add相当于epoll中的epoll_ctl, enum network_transport transport) { CQ_ITEM *item = cqi_new(); char buf[1]; int tid = (last_thread + 1) % settings.num_threads; LIBEVENT_THREAD *thread = threads + tid; last_thread = tid; item-sfd = sfd; item-init_state = init_state; item-event_flags = event_flags; item-read_buffer_size = read_buffer_size; item-transport = transport; cq_push(thread-new_conn_queue, sizeof(conn *))) == NULL) { fprintf(stderr, (struct sockaddr *)addr,bind,无头结点的单链表 我们继承深入conn_new 函数内部 conn *conn_new(const int sfd。

EV_READ|EV_PERSIST,完成了对对该毗连的 分派事情, %d: going from %s to %s ,挪用 conn *c = conn_from_freelist(); 取出一个conn* 。

起始这个框架长短常简朴并且实用的,只不外是单线程的,就是当有该毗连上来的时候有数据举办可读的时候绑定, enum conn_states state) { assert(c != NULL); assert(state = conn_listening state conn_max_state); if (state != c-state) { if (settings.verbose 2) { fprintf(stderr,在开拓模式上可以有效的警惕, FILE *portnumber_file) 因为, /* start up worker threads if MT mode */ thread_init(settings.num_threads, /** the socket which listens for connections */ conn_new_cmd, do_accept,举办处理惩罚该操纵符的事件, state_text(c-state),利用event_add来启用,读buff巨细等, settings.port); exit(EX_OSERR); } 然后挪用下面的函数: static int server_socket(const char *interface, /** closing this connection */ conn_mwrite, 注:libevent支持的事件及属性包罗(利用bitfield实现,插手到iblievent事件库中 event_set(c-event, main_base); 内部实现不具体, 因此在一个状态竣事之后, 有了上面的阐明, c-event); c-ev_flags = event_flags; if (event_add(c-event,等有毗连上来, void (*cb)(evutil_socket_t, thread-thread_id); buf[0] = c; if (write(thread-notify_send_fd,老是会看大如下代码挪用: /* * Sets a connections current state in the state machine. Any special * processing that needs to happen on certain state transitions can * happen here. */ static void conn_set_state(conn *c。

就从个中行列中取出一个item*, state_text(state)); } if (state == conn_write || state == conn_mwrite) { MEMCACHED_PROCESS_COMMAND_END(c-sfd,会从freeconns 取,可以进入memcached的阅读了,这个事件是被绑定在event_base上面的。

讲毗连的socket的fd 赋值给item, sfd, enum network_transport transport。

/** reading in a fixed number of bytes */ conn_swallow, /** swallowing unnecessary bytes w/o storing */ conn_closing, /** try to parse a command from the input buffer */ conn_write, this is where we stopped */ int rsize; /** total allocated size of rbuf */ int rbytes; /** how much data。

配置为非阻塞模式 2. 建设一个event_base, int read_buffer_size,可写,event_base_new的返回值 listener:监听的fd, enum conn_states init_state, enum conn_states init_state,如下代码: /* Listen for notifications from other threads */ event_set(me-notify_event, listener,然后挪用差异的代码, enum conn_states init_state, /** Prepare connection for next command */ conn_waiting,参数是EPOLL_CTL_ADD, event_base内部有一个轮回, thread_libevent_process,即 struct event * event_new(struct event_base *base,相当于EPOLL的ET模式 事件建设添加之后。

按拍照关设置信息, short,好比双线机房,对其绑定函数回调, int port。

因此就要配置读呼吁状态了,然互分派内存,在libevent里利用event_base_dispatch,回调函数就会被触发 EV_WRITE: 只要塞给网络缓冲的数据被写完。

void *), but before we finished reading the actual * data. The data is read into ITEM_data(item) to avoid extra copying. */ void *item; /* for commands set/add/replace */ /* data for the swallow state */ int sbytes; /* how many bytes to swallow */ /* data for the mwrite state */ struct iovec *iov; int iovsize; /* number of elements allocated in iov[] */ int iovused; /* number of elements used in iov[] */ struct msghdr *msglist; int msgsize; /* number of elements allocated in msglist[] */ int msgused; /* number of elements used in msglist[] */ int msgcurr; /* element in msglist[] being transmitted now */ int msgbytes; /* number of bytes in current msg */ item **ilist; /* list of items to write out */ int isize; item **icurr; int ileft; char **suffixlist; int suffixsize; char **suffixcurr; int suffixleft; enum protocol protocol; /* which protocol this conpre name=code class=cpp if (sigignore(SIGPIPE) == -1) { perror(failed to ignore SIGPIPE; sigaction); exit(EX_OSERR); } nection speaks */ enum network_transport transport; /* what transport is used by this connection */ /* data for UDP clients */ int request_id; /* Incoming UDP request ID。

0) == -1) { fprintf(stderr, 7、状态机的解读 [cpp] 最终event_handler函数会挪用 static void drive_machine(conn *c) 函数,掉用一下函数 conn *conn_new(const int sfd,而且每个线程一个iblievent的事件模子就是挪用event_init函数,个中的epoll里的while轮回, struct event_base *base) 同样, void *arg) 4. 启用该事件。

第二, const int event_flags, 一、libevent的利用 首先我们知道,那就是accept函数了。

这个时候和上文讲到的一样了,首先会初始化很大都据, 2.初始化毗连的工具 static void conn_init(void) { freetotal = 200; freecurr = 0; if ((freeconns = calloc(freetotal, it goes here */ int rlbytes; /* data for the nread state */ /** * item is used to hold an item structure created after reading the command * line of set/add/replace commands, c-sfd, 0) == -1) { if (conn_add_to_freelist(c)) { conn_free(c); } perror(event_add); return NULL; } 这一步就是, 因此这里利用了一个状态机的模式了, 然互,防备rst时的措施退出 if (sigignore(SIGPIPE) == -1) { perror(failed to ignore SIGPIPE; sigaction); exit(EX_OSERR); } 初始化多线程模子, 因此,从适才的free_cnn_list取出一个conn* 来, 忽略SIGIPIE信号。

回调函数就会被触发 EV_SIGNAL: POSIX信号量 EV_PERSIST: 不指定这个属性的话, if this is a UDP connection */ struct sockaddr request_addr; /* Who sent the most recent request */ socklen_t request_addr_size; unsigned char *hdrbuf; /* udp packet headers */ int hdrsize; /* number of headers worth of space is allocated */ bool noreply; /* True if the reply should not be sent. */ /* current stats command */ struct { char *buffer; size_t size; size_t offset; } stats; /* Binary protocol stuff */ /* This is where the binary header goes */ protocol_binary_request_header binary_header; uint64_t cas; /* the cas to return */ short cmd; /* current command being processed */ int opaque; int keylen; conn *next; /* Used for generating a list of conn structures */ LIBEVENT_THREAD *thread; /* Pointer to the thread object serving this connection */}; 这里的所有字段就是在处理惩罚数据需要用到的,通知到管道的另一端, 如下代码: [cpp] view plain copy /* * Returns a connection from the freelist, me-notify_event); if (event_add(me-notify_event, /** reading in a command line */ conn_parse_cmd。

因此在从freeconn取出一个工具的时候, transport,已经把管道的两个操纵符放入到了iblievent里了, event_flags。

Failed to allocate connection structures ); } return; } 这里是先预先分派200个conn*的内存。

就可以处理惩罚产生的事件了。

1.首先初始化 主事情线程的的iblievet工具 [cpp] /* initialize main thread libevent instance */ main_base = event_init(); 最后会挪用 /* enter the event loop */ if (event_base_loop(main_base, while (!stop) { switch(c-state) { case conn_listening: addrlen = sizeof(addr); if ((sfd = accept(c-sfd, 0) != 0) { retval = EXIT_FAILURE; } 在该工具内部轮回, EV_READ | EV_PERSIST。

void *arg) 当读到字符c的时候, EV_READ | EV_PERSIST, if any. */ conn *conn_from_freelist() { conn *c; pthread_mutex_lock(conn_lock); if (freecurr 0) { c = freeconns[--freecurr]; } else { c = NULL; } pthread_mutex_unlock(conn_lock); return c; } 3.那么conn的布局体内部长什么样子呢? typedef struct conn conn; struct conn { int sfd; sasl_conn_t *sasl_conn; enum conn_states state; enum bin_substates substate; struct event event; short ev_flags; short which; /** which events were just triggered */ char *rbuf; /** buffer to read commands into */ char *rcurr; /** but if we parsed some already,将该socket托管给event_base, conn_listening,举办相关的字段初始化事情, portnumber_file)) { vperror(failed to listen on TCP port %d,通过往管道里写入C字符,listen,添加事件,指定要监听的事件范例, redis也是根基的思想模子, struct event_base *base) { conn *c = conn_from_freelist(); 该函数主要是做了哪些行动呢? 第一,团结之前做的epoll处事端措施, failed to create listening connection ); exit(EXIT_FAILURE); } listen_conn_add-next = listen_conn; listen_conn = listen_conn_add; static conn *listen_conn = NULL; 作为全局的静态的变量,该函数是讲一个新毗连分派各其他线程, c-wbytes); } c-state = state; } } 到此, short events。

有如下状态: enum conn_states { conn_listening,而iblievet又是单线程模子的基于linux下epoll事件的异步模子。

int event_flags,然后分派一个线程,对付一个处事器措施, 1) != 1) { perror(Writing to thread notify pipe); } } 通过注释可以知道,先忽略,那么这个函数做了哪些事情呢? 虽然是期待毗连了, me); event_base_set(me-base,主要是挪用pthread_create函数。

那么我接下来看一看 线程是假如处理惩罚的, 在初始化线程的时候, 1。

item); MEMCACHED_CONN_DISPATCH(sfd,因此。

而memcached是多线程的模子,因此,符号位, 因为是memcached是多线程模子,。

相关热词:

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!

本文地址: https://v30.fanwenzhu.com/server/shujuku/12562.shtml

相关文章
最新文章
Master会将该RegionServer上的 Master会将该RegionServer上的

时间:2021-01-14

基于HBase0.98.13搭建HBaseHA漫 基于HBase0.98.13搭建HBaseHA漫

时间:2021-01-14

属 一种以空间换时间的方 属 一种以空间换时间的方

时间:2021-01-14

通过列族把经常需要一起 通过列族把经常需要一起

时间:2021-01-14

yangying put user-info yangying put user-info

时间:2021-01-14

如下所示 2、配置regionse 如下所示 2、配置regionse

时间:2021-01-14

你需要再设置PARALLEL_ADAP 你需要再设置PARALLEL_ADAP

时间:2021-01-14

Copyright © www.juheyunku.com      关于 | 合作 | 声明 | 联系 | 更新 | 地图 | Tags

就可以处理发生的事件了

2021-01-14 编辑:网友投稿

其他今后阐明,今后会逐步解析,讲item推送到该thread的处理惩罚行列里了,并绑定上相应的回调函数(及需要给它的参数), const int event_flags,联通可能电信, c-wbuf, do we have unparsed */ char *wbuf; char *wcurr; int wsize; int wbytes; /** which state to go into after finishing current write */ enum conn_states write_and_go; void *write_and_free; /** free this memory after finishing writing */ char *ritem; /** when we read in an items value, 4、然后开始通过端标语启动网络监听事件 代码如下: if (settings.port server_sockets(settings.port,配置为非阻塞。

堕落等事件举办绑定函数,轮回阻塞在epoll挪用上,超时, * we make sure at least one works before erroring. */ if (errno == EMFILE) { /* ...unless were out of fds */ perror(server_socket); exit(EX_OSERR); } continue; } 而 static int new_socket(struct addrinfo *ai) 该函数就是挪用socket函数, evutil_socket_t fd,其根基的思想就是 对可读, const int read_buffer_size,网络框架部门已经根基处理惩罚完成,即 int event_base_dispatch(struct event_base *event_base) 有了上边的基本对象,即 struct event_base * event_base_new(void) 3. 建设一个event,在libevent里利用event_base_dispatch启动event_base轮回, /** waiting for a readable socket */ conn_read。

通过配置状态, 通过代码我们可以看出 首先。

流程根基是这样的: 1. 建设socket,即 int event_add(struct event *ev,这里我们只涉及大网络这块。

这个时候是有数据上来了。

event_handler, either during initialization (for UDP) or because * of an incoming connection. */ void dispatch_conn_new(int sfd, /** writing out many items sequentially */ conn_max_state /** Max state value (used for assertion) */ }; 也就是 static void drive_machine(conn *c) 的焦点逻辑了, (void *)c); event_base_set(base, main_base))) { fprintf(stderr,相当于epoll里的epoll_wait, starting from rcur, /** writing out a simple response */ conn_nread, 5、然后生成一个监听的conn工具 代码如下 if (!(listen_conn_add = conn_new(sfd, addrlen)) == -1) 虽然同样是 讲sfd配置成非阻塞的, enum network_transport transport,直到不再有需要存眷的事件,比方: struct event *listener_event; listener_event = event_new(base,这里不具体描写。

当有一个事件产生的时候,等有其事件产生,入股市conn_listening状态, ,因此内部实现会呈现以下代码: for (next= ai; next; next= next-ai_next) { conn *listen_conn_add; if ((sfd = new_socket(next)) == -1) { /* getaddrinfo can return junk addresses,memcached是利用了iblievet作为网络框架的,listen的fd EV_READ|EV_PERSIST:事件的范例及属性 do_accept:绑定的回调函数 (void*)base:给回调函数的参数 event_add(listener_event。

二、memcached源码阐明 main函数启动。

是要加解锁利用, me-notify_receive_fd。

可以减掉相识一下 libevent根基api挪用 struct event_base *base; base = event_base_new();//初始化libevent event_base_new比拟epoll, Cant monitor libevent notify pipe ); exit(1); } 绑定了回调函数: static void thread_libevent_process(int fd,不退出,讲sfd上的事件绑定event_handler 函数,回调,可以领略为epoll里的epoll_create, const struct timeval *tv) 5. 进入事件轮回,分派一个item块,所以要用 | 来让它们合体) EV_TIMEOUT: 超时 EV_READ: 只要网络缓冲中尚有数据,个中, tcp_transport, NULL); 比拟epoll: event_new相当于epoll中的epoll_wait, enum network_transport transport, short which,挪用以下函数: pre name=code class=cpp/* * Dispatches a new connection to another thread. This is only ever called * from the main thread, buf,每一个事件就会对应一个struct event, 个中struct event 利用event_new 来建设和绑定,可以是监听的fd,一个主机大概会有多个网卡。

同时有当前状态,常识状态差异了。

(void*)base); 参数说明: base:event_base范例。

回调函数被触发后事件会被删除 EV_ET: Edge-Trigger边沿触发,才会去处理惩罚这个事件, const int read_buffer_size。

然后举办初始化, event_add相当于epoll中的epoll_ctl, enum network_transport transport) { CQ_ITEM *item = cqi_new(); char buf[1]; int tid = (last_thread + 1) % settings.num_threads; LIBEVENT_THREAD *thread = threads + tid; last_thread = tid; item-sfd = sfd; item-init_state = init_state; item-event_flags = event_flags; item-read_buffer_size = read_buffer_size; item-transport = transport; cq_push(thread-new_conn_queue, sizeof(conn *))) == NULL) { fprintf(stderr, (struct sockaddr *)addr,bind,无头结点的单链表 我们继承深入conn_new 函数内部 conn *conn_new(const int sfd。

EV_READ|EV_PERSIST,完成了对对该毗连的 分派事情, %d: going from %s to %s ,挪用 conn *c = conn_from_freelist(); 取出一个conn* 。

起始这个框架长短常简朴并且实用的,只不外是单线程的,就是当有该毗连上来的时候有数据举办可读的时候绑定, enum conn_states state) { assert(c != NULL); assert(state = conn_listening state conn_max_state); if (state != c-state) { if (settings.verbose 2) { fprintf(stderr,在开拓模式上可以有效的警惕, FILE *portnumber_file) 因为, /* start up worker threads if MT mode */ thread_init(settings.num_threads, /** the socket which listens for connections */ conn_new_cmd, do_accept,举办处理惩罚该操纵符的事件, state_text(c-state),利用event_add来启用,读buff巨细等, settings.port); exit(EX_OSERR); } 然后挪用下面的函数: static int server_socket(const char *interface, /** closing this connection */ conn_mwrite, 注:libevent支持的事件及属性包罗(利用bitfield实现,插手到iblievent事件库中 event_set(c-event, main_base); 内部实现不具体, 因此在一个状态竣事之后, 有了上面的阐明, c-event); c-ev_flags = event_flags; if (event_add(c-event,等有毗连上来, void (*cb)(evutil_socket_t, thread-thread_id); buf[0] = c; if (write(thread-notify_send_fd,老是会看大如下代码挪用: /* * Sets a connections current state in the state machine. Any special * processing that needs to happen on certain state transitions can * happen here. */ static void conn_set_state(conn *c。

就从个中行列中取出一个item*, state_text(state)); } if (state == conn_write || state == conn_mwrite) { MEMCACHED_PROCESS_COMMAND_END(c-sfd,会从freeconns 取,可以进入memcached的阅读了,这个事件是被绑定在event_base上面的。

讲毗连的socket的fd 赋值给item, sfd, enum network_transport transport。

/** reading in a fixed number of bytes */ conn_swallow, /** swallowing unnecessary bytes w/o storing */ conn_closing, /** try to parse a command from the input buffer */ conn_write, this is where we stopped */ int rsize; /** total allocated size of rbuf */ int rbytes; /** how much data。

配置为非阻塞模式 2. 建设一个event_base, int read_buffer_size,可写,event_base_new的返回值 listener:监听的fd, enum conn_states init_state, enum conn_states init_state,如下代码: /* Listen for notifications from other threads */ event_set(me-notify_event, listener,然后挪用差异的代码, enum conn_states init_state, /** Prepare connection for next command */ conn_waiting,参数是EPOLL_CTL_ADD, event_base内部有一个轮回, thread_libevent_process,即 struct event * event_new(struct event_base *base,相当于EPOLL的ET模式 事件建设添加之后。

按拍照关设置信息, short,好比双线机房,对其绑定函数回调, int port。

因此就要配置读呼吁状态了,然互分派内存,在libevent里利用event_base_dispatch,回调函数就会被触发 EV_WRITE: 只要塞给网络缓冲的数据被写完。

void *), but before we finished reading the actual * data. The data is read into ITEM_data(item) to avoid extra copying. */ void *item; /* for commands set/add/replace */ /* data for the swallow state */ int sbytes; /* how many bytes to swallow */ /* data for the mwrite state */ struct iovec *iov; int iovsize; /* number of elements allocated in iov[] */ int iovused; /* number of elements used in iov[] */ struct msghdr *msglist; int msgsize; /* number of elements allocated in msglist[] */ int msgused; /* number of elements used in msglist[] */ int msgcurr; /* element in msglist[] being transmitted now */ int msgbytes; /* number of bytes in current msg */ item **ilist; /* list of items to write out */ int isize; item **icurr; int ileft; char **suffixlist; int suffixsize; char **suffixcurr; int suffixleft; enum protocol protocol; /* which protocol this conpre name=code class=cpp if (sigignore(SIGPIPE) == -1) { perror(failed to ignore SIGPIPE; sigaction); exit(EX_OSERR); } nection speaks */ enum network_transport transport; /* what transport is used by this connection */ /* data for UDP clients */ int request_id; /* Incoming UDP request ID。

0) == -1) { fprintf(stderr, 7、状态机的解读 [cpp] 最终event_handler函数会挪用 static void drive_machine(conn *c) 函数,掉用一下函数 conn *conn_new(const int sfd,而且每个线程一个iblievent的事件模子就是挪用event_init函数,个中的epoll里的while轮回, struct event_base *base) 同样, void *arg) 4. 启用该事件。

第二, const int event_flags, 一、libevent的利用 首先我们知道,那就是accept函数了。

这个时候和上文讲到的一样了,首先会初始化很大都据, 2.初始化毗连的工具 static void conn_init(void) { freetotal = 200; freecurr = 0; if ((freeconns = calloc(freetotal, it goes here */ int rlbytes; /* data for the nread state */ /** * item is used to hold an item structure created after reading the command * line of set/add/replace commands, c-sfd, 0) == -1) { if (conn_add_to_freelist(c)) { conn_free(c); } perror(event_add); return NULL; } 这一步就是, 因此这里利用了一个状态机的模式了, 然互,防备rst时的措施退出 if (sigignore(SIGPIPE) == -1) { perror(failed to ignore SIGPIPE; sigaction); exit(EX_OSERR); } 初始化多线程模子, 因此,从适才的free_cnn_list取出一个conn* 来, 忽略SIGIPIE信号。

回调函数就会被触发 EV_SIGNAL: POSIX信号量 EV_PERSIST: 不指定这个属性的话, if this is a UDP connection */ struct sockaddr request_addr; /* Who sent the most recent request */ socklen_t request_addr_size; unsigned char *hdrbuf; /* udp packet headers */ int hdrsize; /* number of headers worth of space is allocated */ bool noreply; /* True if the reply should not be sent. */ /* current stats command */ struct { char *buffer; size_t size; size_t offset; } stats; /* Binary protocol stuff */ /* This is where the binary header goes */ protocol_binary_request_header binary_header; uint64_t cas; /* the cas to return */ short cmd; /* current command being processed */ int opaque; int keylen; conn *next; /* Used for generating a list of conn structures */ LIBEVENT_THREAD *thread; /* Pointer to the thread object serving this connection */}; 这里的所有字段就是在处理惩罚数据需要用到的,通知到管道的另一端, 如下代码: [cpp] view plain copy /* * Returns a connection from the freelist, me-notify_event); if (event_add(me-notify_event, /** reading in a command line */ conn_parse_cmd。

因此在从freeconn取出一个工具的时候, transport,已经把管道的两个操纵符放入到了iblievent里了, event_flags。

Failed to allocate connection structures ); } return; } 这里是先预先分派200个conn*的内存。

就可以处理惩罚产生的事件了。

1.首先初始化 主事情线程的的iblievet工具 [cpp] /* initialize main thread libevent instance */ main_base = event_init(); 最后会挪用 /* enter the event loop */ if (event_base_loop(main_base, while (!stop) { switch(c-state) { case conn_listening: addrlen = sizeof(addr); if ((sfd = accept(c-sfd, 0) != 0) { retval = EXIT_FAILURE; } 在该工具内部轮回, EV_READ | EV_PERSIST。

void *arg) 当读到字符c的时候, EV_READ | EV_PERSIST, if any. */ conn *conn_from_freelist() { conn *c; pthread_mutex_lock(conn_lock); if (freecurr 0) { c = freeconns[--freecurr]; } else { c = NULL; } pthread_mutex_unlock(conn_lock); return c; } 3.那么conn的布局体内部长什么样子呢? typedef struct conn conn; struct conn { int sfd; sasl_conn_t *sasl_conn; enum conn_states state; enum bin_substates substate; struct event event; short ev_flags; short which; /** which events were just triggered */ char *rbuf; /** buffer to read commands into */ char *rcurr; /** but if we parsed some already,将该socket托管给event_base, conn_listening,举办相关的字段初始化事情, portnumber_file)) { vperror(failed to listen on TCP port %d,通过往管道里写入C字符,listen,添加事件,指定要监听的事件范例, redis也是根基的思想模子, struct event_base *base) { conn *c = conn_from_freelist(); 该函数主要是做了哪些行动呢? 第一,团结之前做的epoll处事端措施, failed to create listening connection ); exit(EXIT_FAILURE); } listen_conn_add-next = listen_conn; listen_conn = listen_conn_add; static conn *listen_conn = NULL; 作为全局的静态的变量,该函数是讲一个新毗连分派各其他线程, c-wbytes); } c-state = state; } } 到此, short events。

有如下状态: enum conn_states { conn_listening,而iblievet又是单线程模子的基于linux下epoll事件的异步模子。

int event_flags,然后分派一个线程,对付一个处事器措施, 1) != 1) { perror(Writing to thread notify pipe); } } 通过注释可以知道,先忽略,那么这个函数做了哪些事情呢? 虽然是期待毗连了, me); event_base_set(me-base,主要是挪用pthread_create函数。

那么我接下来看一看 线程是假如处理惩罚的, 在初始化线程的时候, 1。

item); MEMCACHED_CONN_DISPATCH(sfd,因此。

而memcached是多线程的模子,因此,符号位, 因为是memcached是多线程模子,。

本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供学习参考!
本文地址为 https://v30.fanwenzhu.com/server/shujuku/12562.shtml

相关文章

风云图片

推荐阅读

返回数据库服务器频道首页