首先,一个由多台机器组成的分布式系统必然是多进程的,因为进程不能跨 OS 边界。在这个前提下,我们把目光集中到一台机器,一台拥有至少 4 个核的普通服务器。如果要在一台多核机器上提供一种服务或执行一个任务,可用的模式有:
运行一个单线程的进程
运行一个多线程的进程
运行多个单线程的进程
运行多个多线程的进程
从功能上讲,没有什么是多线程能做到而单线程做不到的。一个程序要做到多线程大致要做到:
适用多线程的场景:
有多个 CPU 可用。单核机器上多线程的优势不明显;
线程间有共享数据。如果没有共享数据,用模型 3b 就行,虽然我们应该把线程间的共享数据降到最低,但不代表没有;
共享的数据是可以修改的,而不是静态的常量表。如果数据不能修改,那么可以在进程间用 shared memory;
提供非均质的服务。即事件的响应有优先级差异,我们可以用专门的线程来处理优先级高的事件,防止优先级反转;
latency 和 throughput 同样重要,不是逻辑简单的 IO bound 或 CPU bound 程序;
能 scale up。一个好的多线程程序应该能享受增加 CPU 数目带来的好处,目前主流是 8 核;
具有可预测的性能。随着负载增加,性能缓慢下降,超过某个临界点之后急速下降,线程数目一般不随负载变化;
多线程能有效地划分责任与功能,让每个线程的逻辑比较简单,任务单一,便于编码。
基于多线程服务器的优点:
1. 对内存的消耗小。线程之间共享整个应用环境,每个线程栈都比较小,一般不到1M
2.cpu上下文切换比较快
3.io的并发能力强。 javaVM可以轻松维护几百个并发线程切换开销,远高于多进程几十个并发进程的处理能力
4.有效利用多核cpu进行并行计算
线程的分类:
IO 线程,这类线程的的主循环是 io multiplexing,等在 select/poll/epoll 系统调用上。这类线程也处理定时事件,当然它的功能不止 IO,有些计算也可以放入其中。
计算线程,这类线程的主循环是 blocking queue,等在 condition variable 上,这类线程一般位于 thread pool 中。