前面讲线程时,提到协程,有朋友问他们之间的差别。虽然我们的重点是从性能角度来展开分析,但这三个概念出现的关键点其实也是性能驱动的。早期,操作系统通过多进程实现多用户分享处理器时间片。在进程内部,如果有慢速的I/O操作,就可能拖慢了进程处理效率。于是出现线程概念,将不同任务隔离在独立的处理器上,依然共享整个内存空间。
在处理大规模任务时,比如大量HTTP连接,很容易触发线程发生上下文切换,不但要让出处理器时间,还会导致高速缓存失效。协程的出现,就是确保让开发者看来,允许任务去等待资源,但实际上线程仍然占用CPU,只是转而去执行其他协程。
进程是操作系统管理分配资源的基本单位,线程是操作系统调度CPU的基本单位。协程是用户态的调度单位,操作系统并不能感知,所以可以做得比较灵活。
进程之间,是没有直接关系的。所以,一个进程的崩溃不会影响到另外一个进程的运行。基于这个特性,在追求高可靠的系统中,往往会采用多进程模型。这和早期Apache这样的多进程模型不一样,早期的操作系统没有线程的概念。和Apache类似一样功能的nginx,采用的也是多进程模式。对于nginx这类系统,采用多进程模式,反而是个不错的解决方案。因为对于HTTP连接来说,彼此之间基本没有什么需要共享的东西,多线程的优势也就不存在了。
像redis这类高共享的系统,采用多进程模式反而不多见,而是不断有单进程多线程的系统出现,试图替代redis。多进程之间的交换,称之为IPC,常见的有网络,管道,像邮槽,消息队列不多见。windows还有其他方式,可以查资料。
共享内存在对性能要求高的系统通常是唯一选择。共享内存的延迟是150纳秒,管道的延迟是7微秒,TCP环回的延迟是21微秒。共享内存技术出现其实非常早,但用得并不如网络库,甚至不如管道技术。主要是因为共享内存控制起来非常困难,很容易出现问题,导致其他进程也受到影响,反而破坏了进程隔离的本意。除非系统对延迟非常敏感,像交易系统,基本都是必需的组件。