老师,你好,有个地方不是很明白,
为什么event_loop_channel_buffer_nolock(eventLoop, fd, channel1, type);是往子线程的数据中增加需要处理的 channel event 对象呢?
void event_loop_channel_buffer_nolock(struct event_loop *eventLoop, int fd, struct channel *channel1, int type) {
//add channel into the pending list
struct channel_element *channelElement = malloc(sizeof(struct channel_element));
channelElement->channel = channel1;
channelElement->type = type;//1 add (1: add 2: delete)
channelElement->next = NULL;
//第一个元素 channel_element是channel的链表,
// eventLoop pending_head和pending_tail维护的是channelElement的链表
//这样的话最终还是event_loop包含了channel(event_loop->channelElement->channel)
if (eventLoop->pending_head == NULL) {
eventLoop->pending_head = eventLoop->pending_tail = channelElement;
} else {
eventLoop->pending_tail->next = channelElement;
eventLoop->pending_tail = channelElement;
}
}
void *event_loop_thread_run(void *arg) {
struct event_loop_thread *eventLoopThread = (struct event_loop_thread *) arg;
pthread_mutex_lock(&eventLoopThread->mutex);
// 初始化化event loop,之后通知主线程
eventLoopThread->eventLoop = event_loop_init_with_name(eventLoopThread->thread_name);
yolanda_msgx("event loop thread init and signal, %s", eventLoopThread->thread_name);
pthread_cond_signal(&eventLoopThread->cond);
pthread_mutex_unlock(&eventLoopThread->mutex);
//子线程event loop run
event_loop_run(eventLoopThread->eventLoop);
}
struct event_loop_thread {
struct event_loop *eventLoop;//主线程和子线程共享
pthread_t thread_tid; /* thread ID */
pthread_mutex_t mutex;
pthread_cond_t cond;
char * thread_name;
long thread_count; /* # connections handled */
};
event_loop_channel_buffer_nolock这个函数中是往eventLoop的链表中注册事件,可是这里的eventLoop是和子线程处理函数
event_loop_thread_run中eventLoopThread->eventLoop不是一个eventLoop啊,这个eventLoopThread->eventLoop不才是主子线程共享的吗?
展开
作者回复: 我们还是用acceptor线程和I/O线程这样来区分比较好。
acceptor线程在发现有连接到达后,通过调用event_loop_channel_buffer_nolock函数,往I/O线程的eventLoop里面增加了新的套接字,也就是你说的注册链表。
这里的关键是每个线程都是一个独立的eventLoop,acceptor有自己的eventLoop,I/O线程有自己的eventLoop。没有主子线程共享eventLoop,一个eventLoop就对应一个线程。