网络处理,我们关心:延迟、吞吐量、健壮性。如何减少延迟,增加吞吐量,提高健壮性。编写网络协议很多时候都是在和异步斗争。
单线程逻辑设计的思路:
所有数据结构的生存期,以及对这些数据结构的access,都用这一根逻辑线程。不需要考虑数据结构的race。把任何耗时的操作都给其他线程(IO线程、定时器线程,DB线程等)做,做完之后向事件队列(多线程安全的队列,其他线程是生产者,逻辑线程是消费者)丢事件。
多线程逻辑设计的思路:
所有数据结构的生存期,以及对这些数据结构的access,不一定在一根线程。需要考虑数据结构的race。网络事件、定时器事件唤醒工作线程(一般通过iocp或者epoll来唤醒)执行所有工作,一般不需要交换到其他线程。
很显然,单线程逻辑多了一层事件队列交换,会增加延迟,以及所有的逻辑都在一根线程上跑,逻辑被阻塞也会带来延迟。其实吞吐量对于rpc来说,是个宏观的概念,尽可能快地消费网络消息就会提升吞吐量。对于高并发的程序,是无法忍受单线程逻辑的。所以大家就开始思考如何提高多线程网络的健壮性。说白了就是如何让数据结构多线程安全。
总结一下:减少延迟就是尽可能少做数据交换。首先网络数据到达内核空间交换到用户空间必不可少。到达用户空间,我们如何保护用户空间的数据结构?对用户空间的数据结构加锁?比如critical section/spin_lock,这种高效率的锁。虽然这类高效锁不需要陷入内核态,但会浪费很多cpu(这类锁的机制是:线程会loop检查临界区释放了没,释放了就执行,cpu会loop test)。更不用说mutex这类需要内核态通知用户态的锁了。给我们吸引最大的肯定是atomic operation来实现lock free数据结构。如何实现lock free呢?这需要从宏观的角度来设计,erlang类似的actor model就出现了。
阅读(4029) | 评论(0) | 转发(2) |