自己对于进程,线程,协程的理解总是一知半解,导致每次用到的时候就查一次相关的资料,无法记忆深刻。
目前的场景是需要使用 playwright 对大量的网站进程动态爬虫,所以想考虑使用进程,线程与协程三者之间两两配合(甚至三者同时使用)来实现最大的效率,不知道该如何下手。
其实我更需要的是通过一次学习彻底建立对于进程,线程与协程的深刻理解,这样才能在面对具体问题时具体分析,所以也想让大家推荐一些书籍(或者学习材料都可以,我猜可能是《深入理解操作系统》方面的知识?)来建立对于进程,线程以及协程的知识体系
1
huyomi 317 天前 1
cpu 密集型任务用多线程。
io 密集型任务用 单线程基于事件并发(也就是协程), 如果混合,则主要线程用单线程基于事件并发,用线程池去把 cpu 密集型任务转成异步任务。 一般不会用多进程,python 用多进程的原因是因为有 GIL 锁 书籍建议你看 操作系统导论 ,就看第一部分 虚拟化(第一部分分为 cpu 虚拟化和内存虚拟化,看 cpu 的就行了) 和第二部分 并发 (基于线程并发,基于事件并发), |
2
fregie 317 天前
不解释原理了,你这种场景直接无脑协程就行了,上下文切换开销最小
当然你要是想更小开销,直接固定线程数 epoll 循环监听 socket,但是我觉得没什么必要 |
4
shrugginG OP @fregie 其实我有一个设想是,单线程(协程)执行任务的话是没法利用多核 CPU 的。我设想了两种方案:一是在开多进程然后每个进程中一个线程(协程);或者是在单进程中开多线程,每个线程都是协程。我不太确定这样的话能不能比一个线程(协程)更加高效呢
|
5
Jony4Fun 317 天前
@shrugginG #4 像 golang 里的 GMP 模型,默认就是把 M ,也就是线程的数量,设置为核心数,然后所有协程在这些线程中调度。协程调度的算法也会影响效率。正常来说两个核心干活,如果活足够多,那肯定是两个核心更高效。如果各自协作不好,就另说了。
|
6
fregie 317 天前
协程的设计都是基于多线程的,能直接利用多核 cpu
比如在 8 核 cpu 的机器上会开 8 个线程(实际可能会更多些),在这 8 个线程上调度一大堆协程,能完全利用起 cpu 资源 |
8
ysc3839 317 天前 via Android
@fregie 协程要看底层库是否支持多线程的,比如 C++的 asio 支持多线程,Python 的 asyncio 或者 Node.js 不支持多线程。
|
9
0o0O0o0O0o 317 天前 via iPhone
一般来说,你这个里面 playwright 是最大的开销吧,按照我的优化思路:
- 你需要 browser pool 之类的东西,减少浏览器进程的频繁销毁创建(无责任推荐 crawlee ,我也没用过) - 真的所有请求都必须要 playwright 吗?例如鉴权、验证码、指纹生成等实现有难度用 playwright 可以理解,但在这些步骤完成后,一些具体的请求是不是可以利用 cookies 脱离 playwright 来实现? 学习进程/协程/线程的区别不适合从你这个项目出发,完毕 |
10
kuituosi 317 天前
进程和线程都是非常基础的概念,基本都是操作系统提供的
协程类似任务调度,一般是语言或框架提供的,运行中的任务如果会堵塞就挂起,让空闲的协程运行 |
12
shrugginG OP @0o0O0o0O0o 感谢解答,其实 Cookie 并不是我主要考虑的,和传统的爬虫目的还不太一样,我爬虫的目的是要收集网站加载过程中的各种数据,就是类似于 Chrome Dev Tools 中的 Network 面板,同时还需要采集一定量的网站指纹,所以还是 playwright ,pupytter 这种的合适一点感觉。那如果脱离开爬虫的场景,有什么比较推荐的可以深刻理解学习进程/协程/线程的学习方法嘛
|
13
0o0O0o0O0o 317 天前
@shrugginG #12
> 目前的场景是需要使用 playwright 对大量的网站进程动态爬虫,所以想考虑使用进程,线程与协程三者之间两两配合(甚至三者同时使用)来实现最大的效率,不知道该如何下手。 我不清楚你的具体业务,我只是针对这段。一般来说,puppteer 、playwright 的应用中,浏览器的固定开销让针对浏览器之外的优化手段都变得很难感知,个人感觉不会有太好的学习效果。 > 那如果脱离开爬虫的场景,有什么比较推荐的可以深刻理解学习进程/协程/线程的学习方法嘛 任意介绍协程的书籍文章教程?介绍协程的时候一般都会顺便对比进程和线程。 |
14
mason961125 317 天前
看到协程我就很想问一句,到底是想说 coroutine ,还是 green thread...
|
15
qi1070445109 317 天前 via Android
用 python 下载的时候,多线程总是跑不满带宽
|
16
kenvix 316 天前
其他的别人都说了,我来补充下多进程的场景吧,通常使用多进程的目的是:
1. 跨语言协作:当项目使用了多种不能在一个运行时一起运行的语言时 2. 用效率为代价换取健壮性:适用于大型项目。使用多进程执行各个模块,某个模块跑飞时不至于整个程序全崩,可以很容易恢复 3. 用效率为代价换取安全性:可以用于执行不是特别靠谱的代码,防止不靠谱代码炸了整个程序 |
17
kenvix 316 天前
@kenvix #16 2 3 就是 Chrome 的做法,每个标签页各自独立,崩溃不会影响其他标签
4. Python 这类有 GIL 的语言,多进程是为了执行 CPU 密集任务,本质是把多进程当多线程用 |
18
kenvix 316 天前
@shrugginG #3 多进程的应用还是非常多的,目前 Windows Explorer 、Windows Service Host 实际上都是在从多线程往多进程改,为了健壮和安全
|
19
Jony4Fun 316 天前
刚刚看到这篇 libevent 讲异步 IO 的,OP 要不一起看看,虽然是 tiny introduction
https://libevent.org/libevent-book/01_intro.html |