我有点纳闷,如果“IO会长时间占用线程”,这里我理解的IO肯定是非阻塞式的IO,那非阻塞IO怎么会长时间占用线程呢?
即使要发的数据包特别长,在socket buffer未满的情况下,本质上也还是内存拷贝(甚至零拷贝),也是不会长时间占用线程的
而如果socket buffer满了,遇见EAGAIN,这时候不应该就地重试send或者sleep或者就地poll,而是应该放弃这次send,转而处理别的连接,等待之前的socket的EPOLLOUT事件之后再重新send,所以没有道理会有一个连接长时间占用线程
而如果是read,你可以level trigger选择read一些,也可以选择edge trigger全部读完或者level trigger也可以选择全部读完,然后一个连接一个连接的过;无论哪种,对所有的连接都是机会均等的,
所以我很纳闷“IO会长时间占用线程”是如何发生的?
另一个角度,相比于你说的接续模式,你协程的实现本质上只是你的应用逻辑的组织形式和调用方式发生了变化,并没有改变你的IO模型(如果你之前就是用的非阻塞IO的话),也就是说从你的IO操作期间,比如调用send,到send返回,这期间你的协程所在的线程不能被别的协程抢占,read同理;那如果以前用接续模式会出现“IO会长时间占用线程”,那换成协程的方式,“IO会长时间占用线程”又是如何凭空消失的?
难道你在非协程的时候,选择一次读完,协程的时候选择读一些,造成了最后的结果差异?按理说一次读完的IO效率会更好才对;或者你在IO读完之后回调应用层逻辑的时候,数据的长短造成了应用层逻辑的行为有显著差异?
总之,对于协程解决了“IO会长时间占用线程”这个结论,我是很纳闷的
【 在 ylh0315 的大作中提到: 】
: 说的非常对。
: 交易管理器的设计,原来是没有协程的。采用接续模式。就是把任务划分成一个个的部分(我管他叫珠子),由IO(epoll,链子)接续起来。这样也能解决80~90%的问题。
: 但是有两个问题:
: ...................
--
FROM 113.120.108.*