使用epoll+线程池+异步网络IO模式开发。
1 一个线程一个epoll,还是共用1个epoll ?
一个线程一个epoll。
一台服务器的IO事件不是固定的吗?为了更快的处理完IO事件。
2 IO多路复用定义:1个线程处理多个IO事件。?
3 EventPoller为什么需要管道写1字节唤醒呢?切换线程
但epoll_wait有超时时间啊?
在ZLToolKit中:
用户操作比如EventPoller::addEvent。假设EventPoller属于线程1,在线程2调用了addEvent。
addEvent:在当前线程,放到_event_map。不是当前线程,async。
async_l:把回调指针放入_list_task,写一字节数据,_pipe.write("", 1);。在线程2中。
在线程1中:EventPoller::onPipeEvent()会读到数据,执行_list_task的回调,回调到线程1的addEvent。
(开始没明白为什么能切换到线程1?_pipe.write是线程1的EventPoller的成员变量。)
runLoop:epoll_wait返回了,判断_event_map是否有该IO事件,如果有就回调。
扩展:什么时候会跨线程?
4 work poller:用于阻塞式dns解析,connect 域名不是ip。
work poller线程个数太多了,是cpu的个数。
5 在线程间调配负载 ?
6 ioctl设置非阻塞,对那些函数起作用?非阻塞等于异步吗?
ioctl(sock, FIONBIO, &ul); 对int socket。
只影响accept/connect、recv、send,不影响select,epoll_wait,后面2个函数参数带超时参数。
非阻塞不等于异步,但大部分使用场景都是异步的。
7 tcp server支持多线程如何实现?
下面是wiki的原文:
在创建一个TcpServer
时,ZLMediaKit会把这个Tcp服务的监听套接字加入到每一个epoll实例,这样如果收到新的RTMP播放请求,那么多个epoll实例会在内核的调度下,自动选择负载较轻的线程触发accept事件。
不是每个EventPoller线程,调用listen函数,而是把listen fd添加到epoll_ctl,EPOLL_CTL_ADD。为了提高性能?
TCP Server创建在EventPoller 1,accept后,假设返回在了EventPoller 2?(因为每个EventPoller线程都监听这个listen fd)如何处理?
答:给其它EventPoller线程也创建了TcpServer。
这样还存在其它问题吗?