进程,线程,协程如何配合可以发挥最大的效率

315 天前
 shrugginG

自己对于进程,线程,协程的理解总是一知半解,导致每次用到的时候就查一次相关的资料,无法记忆深刻。

目前的场景是需要使用 playwright 对大量的网站进程动态爬虫,所以想考虑使用进程,线程与协程三者之间两两配合(甚至三者同时使用)来实现最大的效率,不知道该如何下手。

其实我更需要的是通过一次学习彻底建立对于进程,线程与协程的深刻理解,这样才能在面对具体问题时具体分析,所以也想让大家推荐一些书籍(或者学习材料都可以,我猜可能是《深入理解操作系统》方面的知识?)来建立对于进程,线程以及协程的知识体系

2789 次点击
所在节点    程序员
19 条回复
huyomi
315 天前
cpu 密集型任务用多线程。
io 密集型任务用 单线程基于事件并发(也就是协程),
如果混合,则主要线程用单线程基于事件并发,用线程池去把 cpu 密集型任务转成异步任务。
一般不会用多进程,python 用多进程的原因是因为有 GIL 锁

书籍建议你看 操作系统导论 ,就看第一部分 虚拟化(第一部分分为 cpu 虚拟化和内存虚拟化,看 cpu 的就行了) 和第二部分 并发 (基于线程并发,基于事件并发),
fregie
315 天前
不解释原理了,你这种场景直接无脑协程就行了,上下文切换开销最小
当然你要是想更小开销,直接固定线程数 epoll 循环监听 socket,但是我觉得没什么必要
shrugginG
315 天前
@huyomi 谢谢解答。那我是不是可以理解为其实目前多进程的应用已经不多了,python 那边还有应用的原因是 GIL 的存在呢。
shrugginG
315 天前
@fregie 其实我有一个设想是,单线程(协程)执行任务的话是没法利用多核 CPU 的。我设想了两种方案:一是在开多进程然后每个进程中一个线程(协程);或者是在单进程中开多线程,每个线程都是协程。我不太确定这样的话能不能比一个线程(协程)更加高效呢
Jony4Fun
315 天前
@shrugginG #4 像 golang 里的 GMP 模型,默认就是把 M ,也就是线程的数量,设置为核心数,然后所有协程在这些线程中调度。协程调度的算法也会影响效率。正常来说两个核心干活,如果活足够多,那肯定是两个核心更高效。如果各自协作不好,就另说了。
fregie
315 天前
协程的设计都是基于多线程的,能直接利用多核 cpu
比如在 8 核 cpu 的机器上会开 8 个线程(实际可能会更多些),在这 8 个线程上调度一大堆协程,能完全利用起 cpu 资源
Jony4Fun
315 天前
@shrugginG #4 还是要看你的任务类型,CPU 用得多还是 IO 多,爬虫的话应该是 IO 密集的吧,可以先测一测当前程序的瓶颈是啥。
ysc3839
315 天前
@fregie 协程要看底层库是否支持多线程的,比如 C++的 asio 支持多线程,Python 的 asyncio 或者 Node.js 不支持多线程。
0o0O0o0O0o
315 天前
一般来说,你这个里面 playwright 是最大的开销吧,按照我的优化思路:

- 你需要 browser pool 之类的东西,减少浏览器进程的频繁销毁创建(无责任推荐 crawlee ,我也没用过)

- 真的所有请求都必须要 playwright 吗?例如鉴权、验证码、指纹生成等实现有难度用 playwright 可以理解,但在这些步骤完成后,一些具体的请求是不是可以利用 cookies 脱离 playwright 来实现?

学习进程/协程/线程的区别不适合从你这个项目出发,完毕
kuituosi
315 天前
进程和线程都是非常基础的概念,基本都是操作系统提供的
协程类似任务调度,一般是语言或框架提供的,运行中的任务如果会堵塞就挂起,让空闲的协程运行
shrugginG
315 天前
@Jony4Fun 好滴好滴,非常感谢解答,看来我可以去基于 GMP 再深入了解一下
shrugginG
315 天前
@0o0O0o0O0o 感谢解答,其实 Cookie 并不是我主要考虑的,和传统的爬虫目的还不太一样,我爬虫的目的是要收集网站加载过程中的各种数据,就是类似于 Chrome Dev Tools 中的 Network 面板,同时还需要采集一定量的网站指纹,所以还是 playwright ,pupytter 这种的合适一点感觉。那如果脱离开爬虫的场景,有什么比较推荐的可以深刻理解学习进程/协程/线程的学习方法嘛
0o0O0o0O0o
315 天前
@shrugginG #12

> 目前的场景是需要使用 playwright 对大量的网站进程动态爬虫,所以想考虑使用进程,线程与协程三者之间两两配合(甚至三者同时使用)来实现最大的效率,不知道该如何下手。

我不清楚你的具体业务,我只是针对这段。一般来说,puppteer 、playwright 的应用中,浏览器的固定开销让针对浏览器之外的优化手段都变得很难感知,个人感觉不会有太好的学习效果。

> 那如果脱离开爬虫的场景,有什么比较推荐的可以深刻理解学习进程/协程/线程的学习方法嘛

任意介绍协程的书籍文章教程?介绍协程的时候一般都会顺便对比进程和线程。
mason961125
315 天前
看到协程我就很想问一句,到底是想说 coroutine ,还是 green thread...
qi1070445109
314 天前
用 python 下载的时候,多线程总是跑不满带宽
kenvix
314 天前
其他的别人都说了,我来补充下多进程的场景吧,通常使用多进程的目的是:
1. 跨语言协作:当项目使用了多种不能在一个运行时一起运行的语言时
2. 用效率为代价换取健壮性:适用于大型项目。使用多进程执行各个模块,某个模块跑飞时不至于整个程序全崩,可以很容易恢复
3. 用效率为代价换取安全性:可以用于执行不是特别靠谱的代码,防止不靠谱代码炸了整个程序
kenvix
314 天前
@kenvix #16 2 3 就是 Chrome 的做法,每个标签页各自独立,崩溃不会影响其他标签
4. Python 这类有 GIL 的语言,多进程是为了执行 CPU 密集任务,本质是把多进程当多线程用
kenvix
314 天前
@shrugginG #3 多进程的应用还是非常多的,目前 Windows Explorer 、Windows Service Host 实际上都是在从多线程往多进程改,为了健壮和安全
Jony4Fun
314 天前
刚刚看到这篇 libevent 讲异步 IO 的,OP 要不一起看看,虽然是 tiny introduction
https://libevent.org/libevent-book/01_intro.html

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1005218

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX