高性能服务器工作思路(从根本上了解高并发)
高性能服务器工作思路(从根本上了解高并发)(1)各个进程地址空间相互隔离,这一优点也会变成缺点,那就是进程间要想通信就会变得比较困难,你需要借助进程间通信(IPC,interprocess communications)机制,想一想你现在知道哪些进程间通信机制,然后让你用代码实现呢?显然,进程间通信编程相对复杂,而且性能也是一大问题;多进程并行处理的优点很明显,但是缺点同样明显:(1)编程简单,非常容易理解;(2)由于各个进程的地址空间是相互隔离的,因此一个进程崩溃后并不会影响其它进程;(3)充分利用多核资源。
说起来很简单:不就是一个用户请求吗?服务器根据请求从数据库中捞出这篇文章,然后通过网络发回去吗。其实有点复杂:服务器端到底是如何并行处理成千上万个用户请求的呢?这里面又涉及到哪些技术呢?这篇文章就是来为你解答这个问题的。
一、多进程
历史上最早出现也是最简单的一种并行处理多个请求的方法就是利用多进程。比如在Linux世界中,我们可以使用fork、exec等系统调用创建多个进程,我们可以在父进程中接收用户的连接请求,然后创建子进程去处理用户请求。
这种方法的优点就在于:
(1)编程简单,非常容易理解;
(2)由于各个进程的地址空间是相互隔离的,因此一个进程崩溃后并不会影响其它进程;
(3)充分利用多核资源。
多进程并行处理的优点很明显,但是缺点同样明显:
(1)各个进程地址空间相互隔离,这一优点也会变成缺点,那就是进程间要想通信就会变得比较困难,你需要借助进程间通信(IPC,interprocess communications)机制,想一想你现在知道哪些进程间通信机制,然后让你用代码实现呢?显然,进程间通信编程相对复杂,而且性能也是一大问题;
(2)我们知道创建进程开销是比线程要大的,频繁的创建销毁进程无疑会加重系统负担。幸好,除了进程,我们还有线程。
二、多线程
不是创建进程开销大吗?不是进程间通信困难吗?这些对于线程来说统统不是问题。由于线程共享进程地址空间,因此线程间通信天然不需要借助任何通信机制,直接读取内存就好了。
线程创建销毁的开销也变小了,要知道线程就像寄居蟹一样,房子(地址房间)都是进程的,自己只是一个租客,因此非常的轻量级,创建销毁的开销也非常小。
我们可以为每个请求创建一个线程,即使一个线程因执行I/O操作——比如读取数据库等——被阻塞暂停运行也不会影响到其它线程。
就像这样:
但线程就是完美的、包治百病的吗,显然,计算机世界从来没有那么简单。由于线程共享进程地址空间,这在为线程间通信带来便利的同时也带来了无尽的麻烦。
正是由于线程间共享地址空间,因此一个线程崩溃会导致整个进程崩溃退出,同时线程间通信简直太简单了,简单到线程间通信只需要直接读取内存就可以了,也简单到出现问题也极其容易,死锁、线程间的同步互斥、等等,这些极容易产生bug,无数程序员宝贵的时间就有相当一部分用来解决多线程带来的无尽问题。
虽然线程也有缺点,但是相比多进程来说,线程更有优势,但想单纯地利用多线程就能解决高并发问题也是不切实际的。
因为虽然线程创建开销相比进程小,但依然也是有开销的,对于动辄数万数十万的链接的高并发服务器来说,创建数万个线程会有性能问题,这包括内存占用、线程间切换,也就是调度的开销TG:li9047