re: 论epoll的使用 唐诗 2012-08-30 14:53
@peakflys
单线程,压力测试流量很大,3K都没有问题,这时已经受到带宽限制了。流量小点10K都可以。我们设计只需要1K连接就行了,不够可以加多个网关服,所以绰绰有余了
re: 论epoll的使用 唐诗 2012-08-30 11:09
正因为觉得移出epoll队列不好,但是不移除也不好,所以et是比较好的方式
代码其实相当简单。

write_list_是应用层缓冲区,在epoll写事件来的时候,应用层缓冲区为空的话
设置socket 可写。下次往应用层缓冲区写数据时,检查socket是否可写,如果可写则调用HandleWrite即可。缓冲区写满的时候设置socket不可写就行了。

HandleWrite有两个调用途径,一个是写事件触发,一个是应用层触发(socket有is_writable标记)。

void HandleWrite()
while (true) {
// 应用层缓冲区全部写到TCP缓冲区了, 此时TCP缓冲区还是可写
// et模式下不会再通知应用层, 所以设置下socket writable状态
// 下次应用层数据来的时候检查该状态
if (write_list_.TotalSize() == 0) {
socket_.set_is_writable(true);
return;
}
int n = write(fd, write_list_.ReadPoint(), write_list_.readable_size());
const int error_no = errno;
if (n == -1) { // 写异常
if (error_no == EINTR) {
continue;
}
// 缓冲区已写满, 需要等写事件
if (error_no == EAGAIN) {
socket_.set_is_writable(false);
return;
} else {
HandleError(error_no);
return;
}
} else { // 写正常
write_list_.ReadAdvance(n);
}
}
re: 论epoll的使用 唐诗 2012-08-29 17:08
事实上et要比lt简单的多
re: 论epoll的使用 唐诗 2012-08-29 17:07
楼主没有说到重点,需要注意的是写事件。
a. 对于et来说,应用层向tcp缓冲区写,有可能应用层数据写完了,但是tcp缓冲没有写到EAGAIN事件,那么此时需要在应用层做个标记,表明tcp缓冲区是可写的,否则,由于et是只触发一次,应用层就再也不会被通知缓冲区可写了。
b. 对于lt来说,应用层确实会每次通知可写事件,问题在于,如果应用层没数据需要往Tcp缓冲区写的话,epoll还是会不停的通知你可写,这时候需要把描述符移出epoll,避免多次无效的通知
http://www.cnblogs.com/egametang/archive/2012/07/30/2615808.html
我猜你是网易的,呵呵!
一定要纠结学术上的Liskov 替换原则可以设计两个一模一样的接口,ConnectionEventHandler和DataEventHandler,两者成员函数完全一样,Acceptor、Connector 分别继承这两个类,这样也比到处是boost::bind要好,core掉的时候就不用看着到处的模板目瞪口呆了

不过,既然是一模一样,顺其自然到不如就共用一个接口类了
@陈硕
Liskov 替换原则是个过于理想化的原则,实际使用中需要权衡
@陈硕
更重要的理由就是:我认为这么建模是错的。
Acceptor is-not-a Channel, Acceptor uses a Channel to get readable event notification.
Connector is-not-a Channel, Connector uses a Channel to get writable event notification.

这只是文字上的理解的区别,既然可以用虚函数,那必然可以换个理解,例如:

我们可以这么理解, 把Channel改个名字EventHandler

Acceptor is a EventHandler
Connector is a EventHandler
@陈硕
为什么不可以?理由?
@陈硕
Channel class设计成虚函数,直接继承Channel有啥问题?
看过这个代码,对其中一些设计很不感冒
例如 channel明明可以设计成虚函数接口,结果却硬是用std::function去撸

陈硕估计老是想着用function了。却忘记了虚函数的使用。
例如用boost::bind取代虚函数这篇文章。一个对象级别的函数指针当然可以取代
类级别的虚函数,问题是我需要用大炮打蚊子吗?类带一个函数指针
与每个对象都带一个函数指针,抛开别的不说,就内存都要节省一些。而且用了boost::function调试起来看到一块块模板栈是不是有想死的感觉?

这也算是学会用std::function std::bind的一些人的通病了,啥地方都去用std::function。有玩弄技巧之嫌。

说个搞笑的事情,我们原来的头自从学会用bind这个东西后,没有bind就写不出代码了……