你是怎么理解并发和并行的?
科普-现代操作系统
当代操作系统都是分时系统。所谓分时,就是 OS 会把 CPU 的工作时间分成一个个很小的时间片。OS 内核调度程序会把这些时间片分配给目前所有运行的线程。由于时间片都很短(在 Linux 上为 5ms-800ms),所以我们看到好像自己程序好像一直在运行。
科普-SMP (Symmetric Multi-Processor) 现代对称多处理架构的 CPU
现代一个 CPU 都有多个核心,由于核心的运算速度远远大于内存的存取速度,所以在内存与 CPU 之间增加了多级缓存,用于平衡 CPU 和内存。
这也许是为什么编写并发程序难的罪魁祸首。
如果没有这几层缓存,程序执行的流程应该是这样。
内存读取数据 ==> 计算 ==> 写内存
有了缓存后的执行流程。
数据是否在缓存中 ==> 不存在 ==> 加载数据 ==> 计算 ==> 写内存
|| /\
||=======> 存在 =========>||
这就让原本读写的操作,增加了缓存判断、缓存失效、缓存同步等一些机制,导致我们并发程序没有正确编写就会出现各种数据可见性问题。
引申: MESI-缓存一致性协议
但是,试想下,如果没有 CPU 缓存机制,我们的程序可能会慢几个数量级。
说说并发
这里说的并发是指:concurrency
已经有很多小伙伴说了自己对并发的理解。
就我个人理解,所谓并发,一定是要有状态。所谓状态,就是我们通常说的临界区。如果没有临界区,就谈不上所谓的并发。
可能理解起来有点抽象,我举个栗子。
public static int add(int a, int b) {
return a + b;
}
这段代码的调用,无论进程内多少个线程同时调用。在我看来,这个程序都不是一个并发的程序。
并发
!= 多线程
我们有一个服务器程序,他有两个线程,一个线程做的是每隔 5 秒钟扫描本地磁盘,并打印目录下的所有文件名;另一个线程做的是,每隔 5 秒钟打印下当前时间戳。
你能说这个程序是并发程序么?多个线程的程序,并不意味着是一个并发程序。
来看一个并发的例子:
static final AtomicInteger a = new AtomicInteger(0);
public static int add(int b) {
return a.incrementAndGet() + b;
}
这段程序,如果多个线程调用,那么是一个并发的程序。因为所有线程都会有一个临界区(a),这是所有线程共享的。
所以说,并发是程序层的概念,跟 cpu 无关。
总之,多个线程回去访问一个临界区(有状态),那么程序就是并发程序。同时,我们就要关心如何处理这些临界区的并发问题了。关于怎么处理这里不深讨论。
聊聊并行
这里说的并行指的是:parellelism
还是看例子:
static volatile int a = 0;
public static int add(int b) {
return a+ b;
}
上面的例子,多线程去调用,就是一个并发的程序。
但是,如果在单核 CPU 下执行,他是没有问题的。第一,单核 CPU 读取自己的缓存,所以不会有缓存不一致问题。第二,单核 CPU 时间片分配给不同的线程,他们的执行时看到的数据都是同一份,计算结果也保存在同一块缓存中。
如果放到多核 CPU 下执行,假如我们希望 a 每一次递增的值,都只被计算一次。那么这个程序的执行结果就是不定的。
上面的程序经常被拿来当并发程序的经典教材,说会执行错误。但是这些教材都忘了一个前提条件,多核 CPU 下执行才会出错。
那么并行是什么?
并行就是具备多个 CPU 的情况下,OS 内核可以把多个任务同时(可能相关、可能无关)分配给多个 CPU 执行。
如果这个程序是上面的例子,就会存在 CPU1 和 CPU2 同时访问上面例子中的 a(假如=0)变量,将它从内存中 load 进 缓存行 (CPU 都是以缓存行的形式加载内存中的数据的,一般为 64 byte)。
之后,都传入参数 b(假如=1),最后得到的结果都是 1。
如果我们是希望 a 的每一次递增的值被计算一次,
那么这个并发程序在多 CPU 下并行执行的时候就会有问题。我们就需要使用锁,cas 等进行并发控制。
并行跟程序无关,跟 CPU 架构相关。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论