• 小蚂蚁
    2019-12-11
    老师,你好,有个地方不是很明白,
    为什么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就对应一个线程。

    
     1
  • xupeng1644
    2020-02-10
    event_loop_init中,代码片段:
    event_loop_add_channel_event(eventLoop, eventLoop->socketPair[0], channel);
    其中传入的应该是socketPair[1]吧。
    
    
  • 鱼向北游
    2019-10-29
    回老师上一条 把代码netty贴过来了
         private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
            private final AtomicInteger idx = new AtomicInteger();
            private final EventExecutor[] executors;

            PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
                this.executors = executors;
            }

            @Override
            public EventExecutor next() {
                return executors[idx.getAndIncrement() & executors.length - 1];
            }
        }

        private static final class GenericEventExecutorChooser implements EventExecutorChooser {
            private final AtomicInteger idx = new AtomicInteger();
            private final EventExecutor[] executors;

            GenericEventExecutorChooser(EventExecutor[] executors) {
                this.executors = executors;
            }

            @Override
            public EventExecutor next() {
                return executors[Math.abs(idx.getAndIncrement() % executors.length)];
            }
        }
    展开

    作者回复: 感觉还是按照顺序在取线程号啊。

     1
    
  • MoonGod
    2019-10-23
    老师关于加锁这里有个疑问,如果加锁的目的是让主线程等待子线程初始化event loop。那不加锁不是也可以达到这个目的吗?主线程while 循环里面不断判断子线程的event loop是否不为null不就可以了?为啥一定要加一把锁呢?

    作者回复: 好问题, 我答疑统一回答吧。

     1
    
  • 鱼向北游
    2019-10-23
    netty选子线程是两种算法,都是有个原子自增计数,如果线程数不是2的幂用取模,如果是就是按位与线程数减一

    作者回复: 嗯,涨知识了,代码贴一个?

    
    
  • 程序水果宝
    2019-10-23
    求完整的代码链接

    编辑回复: 代码链接请去详情页查看。

    
    
我们在线,来聊聊吧