惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Simon Willison's Weblog
Simon Willison's Weblog
P
Privacy International News Feed
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Troy Hunt's Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
V2EX - 技术
V2EX - 技术
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
O
OpenAI News
Cloudbric
Cloudbric
Google Online Security Blog
Google Online Security Blog
Schneier on Security
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Help Net Security
Help Net Security
Cyberwarzone
Cyberwarzone
G
GRAHAM CLULEY
L
Lohrmann on Cybersecurity
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Spread Privacy
Spread Privacy
NISL@THU
NISL@THU
N
News and Events Feed by Topic
T
Tenable Blog
S
Security @ Cisco Blogs
N
News and Events Feed by Topic
The Hacker News
The Hacker News
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
P
Proofpoint News Feed
Webroot Blog
Webroot Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 三生石上(FineUI控件)
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Jina AI
Jina AI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
L
LangChain Blog
The Register - Security
The Register - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东

Coroutines - 标签 - This Cute World

暂无文章

进程线程协程与并发并行
於清樂 · 2018-01-23 · via Coroutines - 标签 - This Cute World

个人笔记,不保证正确。

每一个进程,都可以看作是一个完整的 Program,它有自己完全独立的内容。不与其他进程直接共享数据。(一个工作(job)可以由多个 process 完成,例如电脑上的qq/360就会有好几个进程,这种程序可能会有一个守护进程,当主进程挂掉,它会自动重启主进程。)

每个进程可以由多个线程组成。进程抽象由操作系统提供,Linux 是使用 fork 函数,Windows 是用 CreateProcess。

属于同一个进程的线程之间,是共享一套工作内容的。这使得线程的创建和移除开销很小,但同时也使编程变得复杂。

关于线程,分用户级线程和内核级线程。不同的语言中,这两种线程的对应关系也不尽相同。

  • 多对一模型将多个用户级线程映射到一个内核级线程,线程管理在用户空间完成,这种模型下操作系统并不知道多线程的存在。Python 就是这种模型。

    • 优点:线程管理是在用户空间进行的,切换上下文开销比较小,性能较高。
    • 缺点:当一个线程在使用内核服务时被阻塞,那么整个进程都会被阻塞;多个线程不能并行地运行在多处理机上。
  • 一对一模型将每个用户级线程映射到一个内核级线程。Java的线程就属于这种模型。

    • 优点:当一个线程被阻塞后,允许另一个线程继续执行,所以并发能力较强;能很好的利用到 CPU的多核心。
    • 缺点:每创建一个用户级线程都需要创建一个内核级线程与其对应,这样创建线程的开销比较大,会影响到应用程序的性能。并且切换线程要进出内核,代价比较大。
  • 多对多模型将n个用户级线程映射到m个内核级线程上,要求 m <= n。GO(1.5之后)的协程就属于这种线程模型。

    • 特点:既克服了多对一模型的并发度不高的缺点,又克服了一对一模型的一个用户进程占用太多内核级线程,开销太大的缺点。又拥有多对一模型和一对一模型各自的优点。

如果说线程是轻量级的进程,那么协程就是轻量级的线程。线程跑在进程里,协程就跑在线程里。

优点:

  1. 协程是跑在同一个线程里,并且是由程序本身来调度的。协程间的切换就是函数的调用,完全没有线程切换那么大的开销。
    • 线程的数量越多,协程的优势越大
  2. 因为协程是程序调度的,它实际上是串行运行的,因此不需要复杂的锁机制来保证线程安全。
    • 在协程中控制共享资源不加锁,只需要判断状态就好了。这免去了锁机制带来的开销。

因为协程跑在单个线程内,所占用的 CPU 资源有限,所以多协程并不能提升计算性能。不仅如此,因为多了程序本身的调度开销,计算密集型程序的性能反而会下降。

此外,协程代码中决不能出现阻塞,否则整个线程都会停下来等待该操作完成,这就麻烦了。

协程适合用于 IO 密集型任务,可用于简化异步 IO 的 callback hell。例如 Python 的 asyncio 就是用协程实现的。

由此,又引出两个名词:

  1. 并发(Concurrent):多个任务交替进行。
  2. 并行(Parallel):多个任务同时进行。

一张图说明两者的差别

Note:进程 和 线程 都可能是 并发 或 并行 的。关键看你程序的运行状态。多核是并行的前提。并发则只要求交替执行,因此单核也没问题。

  1. 同步:不同程序单元为了完成某个任务,在执行过程中需靠某种通信方式以协调一致,称这些程序单元是同步执行的。
    • 多线程编程中,所有修改共享变量的行为,都必须加锁,保证顺序执行,保证同步。或者加原子锁,保证该修改操作是原子的。
    • 同步意味着有序
  2. 异步:为完成某个任务,不同程序单元之间过程中无需通信协调,也能完成任务的方式。
    • 不相关的程序单元之间可以是异步的。比如爬虫下载网页
    • 异步意味着无序