并发、并行、线程、进程、异步、同步、阻塞、非阻塞

并发(Concurrency)与并行(Parallelism)

并发:两个或多个事件在同一时间间隔内发生。这些事情宏观上同时发生,微观上交替进行。

并行:两个或多个事件在同一时刻同时发生。

并发

假设你同时被赋予了唱歌和吃饭的任务。在给定的时间,你要么唱歌,要么吃东西,因为在这两种情况下,你的嘴都会受到影响。因此,为了做到这一点,你会吃一段时间,然后唱歌,重复这个过程,直到你的食物吃完或歌曲结束。所以你并发完成了任务。

在单核环境中,通过上下文切换,在同一时间段内执行的任务发生并发,即在特定的时间段,只有一个任务被执行。

img

在多核环境中,可以通过同时执行多个任务的并行来实现并发。但是并发性仍不可少。比如对于4核CPU,同一时刻可以用四个程序并行执行,但通常我们需要四个以上程序同时工作,此时就需要并发了。

并行

假设你有两项任务:做饭和打电话给你的朋友。你可以同时做这两件事。你既可以做饭,也可以打电话。现在你是在并行地做你的任务。

并行意味着同时执行两个或多个任务。

img

关系

  • Concurrency and Parallelism refer to computer architectures which focus on how our tasks or computations are performed.
  • 在单核环境中,通过上下文切换,在同一时间段内执行的任务发生并发,即在特定的时间段,只有一个任务被执行。
  • 在多核环境中,可以通过同时执行多个任务的并行来实现并发。

线程(Threads)与进程(Processes)

线程是CPU调度的最小单元,进程是资源分配的最小单元。

进程是running program的一个instance,一个program可以有多个进程。

img

同步(Synchronous)和异步(Asynchronous)

同步:任务一个接一个地执行。每个任务等待任何先前的任务完成,然后执行。

异步:当一个任务被执行时,您可以切换到另一个任务,而无需等待前一个任务完成。

同步

想象一下,你被安排写两封信,一封是给你妈妈的,另一封是给你最好的朋友的。你不能同时写两封信,除非你是个两手都能写的人。

在同步编程模型中,任务一个接一个地执行。每个任务都会等待之前的任何任务完成,然后执行。

异步

想象一下,有人让你做三明治,然后在洗衣机里洗衣服。你可以把衣服放进洗衣机里,不用等它洗好,你就可以去做三明治了。

在这里,您异步执行了这两个任务。在异步编程模型中,当执行一项任务时,您可以切换到另一项任务,而无需等待前一项任务完成。

那么,在同步调用下,调用方不再继续执行而是暂停等待,被调函数执行完后很自然的就是调用方继续执行,那么异步调用下调用方怎知到被调函数是否执行完成呢?

这就分为了两种情况:

  1. 调用方根本就不关心执行结果
  2. 调用方后续需要知道执行结果

第一种情况比较简单,该情况无需讨论。第二种情况下通常有两种实现方式:

  • 通知机制,也就是说当任务执行完成后发送信号用来通知调用方任务完成,注意这里的信号就有很多实现方式了,Linux中的signal,或者使用信号量等机制都可以实现。

  • 回调,也就是我们常说的callback,

关系

单线程和多线程中的同步和异步

同步

单线程,每个任务都被一个接一个地执行。每个任务都等待其前一个任务执行。

img

多线程:Tasks get executed in different threads but wait for any other executing tasks on any other thread.

img

异步

单线程:任务开始执行时不需要等待其他任务完成。在给定的时间,执行单个任务。

img

多线程:Tasks get executed in different threads without waiting for any tasks and independently finish off their executions.

img

同步、异步与并发性、并行性

异步编程模型帮助我们实现并发。

多线程环境中的异步编程模型是实现并行性的一种方式。

同步、异步与阻塞、非阻塞

详细参考怎样理解阻塞非阻塞与同步异步的区别? - 萧萧的回答 - 知乎

  1. 阻塞/非阻塞, 同步/异步的概念要注意讨论的上下文:
  • 在进程通信层面, 阻塞/非阻塞, 同步/异步基本是同义词, 但是需要注意区分讨论的对象是发送方还是接收方。发送方阻塞/非阻塞(同步/异步)和接收方的阻塞/非阻塞(同步/异步) 是互不影响的。
  • 在 IO 系统调用层面( IO system call )层面, 非阻塞 IO 系统调用异步 IO 系统调用存在着一定的差别, 它们都不会阻塞进程, 但是返回结果的方式和内容有所差别, 但是都属于非阻塞系统调用( non-blocing system call )。具体来说,
    • 一个非阻塞I/O 系统调用 read() 操作立即返回的是任何可以立即拿到的数据, 可以是完整的结果, 也可以是不完整的结果, 还可以是一个空值。
    • 异步I/O系统调用 read()结果必须是完整的, 但是这个操作完成的通知可以延迟到将来的一个时间点。
  1. 非阻塞系统调用(non-blocking I/O system call 与 asynchronous I/O system call) 的存在可以用来实现线程级别的 I/O 并发, 与通过多进程实现的 I/O 并发相比可以减少内存消耗以及进程切换的开销。

总结

Concurrency and Parallelism -> Way tasks are executed.

Synchronous and Asynchronous -> Programming model.

Single Threaded and Multi-Threaded -> The environment of task execution.

参考

Concurrency, Parallelism, Threads, Processes, Async, and Sync — Related?
从小白到高手,你需要理解同步与异步
怎样理解阻塞非阻塞与同步异步的区别? - 萧萧的回答 - 知乎

------ 本文结束------
坚持原创技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道