• 传说中的成大大
    2019-10-21
    第二道题 就是一个扩容啊 类似std的vector自动扩容 而且每次成倍的增长
    
     2
  • 唔多志
    2019-10-22
    map_make_space() 函数里 realloc() 和 memset() 两个函数用的很巧妙啊,realloc() 用来扩容,且把旧的内容搬过去,memset() 用来给新申请的内存赋 0 值。赞,C 语言太强大了。

    作者回复: 显然是看进去了。

    
     1
  • LDxy
    2019-10-21
    event_loop_handle_pending_add函数中,
    map->entries[fd] = calloc(1, sizeof(struct channel *));
    map->entries[fd] = channel;
    这两行都给map->entries[fd] 赋值,后一行不是覆盖上一行的赋值了么?有何用意?

    作者回复: 这块是我的疏忽,应该直接赋值的,可能是开始我撰写的时候channel对象的初始化放到了event_loop_handle_pending_add函数中,后来把channel对象的初始化重构到外面,这里忘记删掉了。

    已经更新文稿(待周一编辑更新)和github代码,感谢指正。

    
     1
  • chs
    2019-12-24
    老师,您为了支持poll和epoll,抽象出了struct event_dispatcher结构体,然后在epoll_dispatcher.c 和poll_dispatcher.c中分别实现struct event_dispatcher中定义的接口。请问epoll_dispatcher.c中的 const struct event_dispatcher epoll_dispatcher变量 和poll_dispatcher.c中的const struct event_dispatcher poll_dispatcher变量怎样让其他文件知道其定义的。我自己写的提示上边两个变量未定义。

    作者回复: 这个是通过下面的方式在头文件中声明:

    extern const struct event_dispatcher poll_dispatcher;
    extern const struct event_dispatcher epoll_dispatcher;

    
    
  • 小蚂蚁
    2019-12-01
    老师你好,问个基础的问题:
    epoll_dispatcher和poll_dispatcher都有,在添加,删除,更新事件时都有如下的逻辑,其中if条件中的判断怎么理解啊?
    if (channel1->events & EVENT_READ) {
            events = events | POLLRDNORM;
        }

        if (channel1->events & EVENT_WRITE) {
            events = events | POLLWRNORM;
        }
    展开

    作者回复: 这里是位与操作,举个例子,EVENT_READ可能为二进制的00000010,如果有可读事件发生,那么在这个位上的bit值一定位1,这样位与的结果就说明这个事件发生了。之所以采用位与,而不是位或,是因为只需要关心这一种类型的事件。

     1
    
  • Steiner
    2019-10-22
    请问channel里的fd也需要设置为非阻塞吗

    作者回复: channel里的fd是在有连接建立时创建好的,当然,也是被设置为非阻塞的,这里channle对象不需要关系fd的属性。

    
    
  • 沉淀的梦想
    2019-10-22
    看到map_make_space里面的realloc函数,突然有个疑问,既然操作系统底层支持直接在原数组上扩充内存,为什么Java不支持直接在原数组上扩容呢,ArrayList每次扩容都要重新拷贝一份原来的数据。

    作者回复: 好问题,我试着解读一下:
    第一,Java有JVM实现,在Java的世界里,它的对象是统一被JVM管理的,包括GC,对象管理,基于这一层考虑,它不可能使用系统级别的对象内存管理,这两个没有办法调和,就像你举的例子,如果我们创建一个类似ReallocList对象,那么这个对象的内存管理完全不是JVM那套了;

    第二,JVM是一个跨OS的实现,我不知道是否Windows也有类似realloc函数,这样就需要JVM做到跨OS的直接内存接管,这和Java的思想是不一致的。

     2
    
  • 传说中的成大大
    2019-10-21
    老师 你好 问你一个和课程沾点点边的关系的问题哈,虽然我晓得什么这样模式那样模式 但是还是不会设计 比如像老师为课程设计的框架 回调都是两层 为什么要这样设计我却不明白 有没有什么规范啥的可以指导一下 可能真的是没好好学过设计模式,既然现在都涉及到要自己动手一个服务器框架了 我也想解决设计这方面的问题,希望老师点播一下

    作者回复: 放到统一答疑里了。

    
    
  • 传说中的成大大
    2019-10-21
    而且新连接,创建的channel对象上的回调也应该是tcp_connection上的回调

    作者回复: 统一答疑中解释。

    
    
  • 传说中的成大大
    2019-10-21
    lib/tcp_connection.c最终是在lib/tcp_connection.c 第22行执行了应用层的readcallback函数执行 epoll-server-multithreads.c onMessage为什么要封装两次呢? 封装一个tcp_connection是为了隐藏读取字节流的实现吗,主要是套接字层? tcp_server层主要就是引用层的这样理解可以吗?

    作者回复: 统一答疑中解释。

    
    
  • 传说中的成大大
    2019-10-21
    今天仔细研读了老师的代码突然发现有两层回调
    1. epoll-server-multithreads.c里面写的有回调 并且赋给了tcp_server
    2. tcp_connection.c 实现了 handle_read handle_write 等等事件的回调 为什么要封装两层回调呢 我设计模式没怎么学过 希望老师指点哈

    作者回复: 统一答疑中解释。

    
    
  • 传说中的成大大
    2019-10-21
    epollDispatcherData->events = calloc(MAXEVENTS, sizeof(struct acceptor));
    这一行不太明白为什么要分配MAXEVENTS* sizeof( struct acceptor )这么多内存?我的关注点在sizeof(
    struct acceptor ),为什么取它的大小?

    作者回复: 笔误,已修复。

    
    
  • 鱼向北游
    2019-10-21
    老师的程序读了一遍,c版的netty,果然高手们的思路都是相通的

    作者回复: 是操作系统提供的能力就是这样,大家都这么发挥了。

    
    
  • 刘系
    2019-10-21
    第二课后题:当描述字大于channel_map的容量时,map_make_space会被调用。在map初始化时,容量为0,往map里写描述字时先给容量为32,如果描述字仍然大于等于32将会使容量右移一位,也就是描述字容量增加两倍再与要写入的描述字进行比较,直至容量大于要写入的描述字。然后使用realloc进行空间开辟,保留原有空间,扩展新空间。将新空间内存置0。最后更新map
     1
    
我们在线,来聊聊吧