你是怎么理解并发和并行的?

发布于 2025-02-01 16:22:47 字数 2732 浏览 3 评论 0

科普-现代操作系统

当代操作系统都是分时系统。所谓分时,就是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

伴我心暖

暂无简介

文章
评论
352 人气
更多

推荐作者

alipaysp_giMRmwQ3mK

文章 0 评论 0

爱她像谁

文章 0 评论 0

清风疏影

文章 0 评论 0

mb_OO8gCSDD

文章 0 评论 0

佚名

文章 0 评论 0

汹涌人海

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文