V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shrugginG
V2EX  ›  程序员

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

  •  
  •   shrugginG · 117 天前 · 2324 次点击
    这是一个创建于 117 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    19 条回复    2024-01-03 12:47:11 +08:00
    huyomi
        1
    huyomi  
       117 天前   ❤️ 1
    cpu 密集型任务用多线程。
    io 密集型任务用 单线程基于事件并发(也就是协程),
    如果混合,则主要线程用单线程基于事件并发,用线程池去把 cpu 密集型任务转成异步任务。
    一般不会用多进程,python 用多进程的原因是因为有 GIL 锁

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

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

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

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

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

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

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

    任意介绍协程的书籍文章教程?介绍协程的时候一般都会顺便对比进程和线程。
    mason961125
        14
    mason961125  
       117 天前
    看到协程我就很想问一句,到底是想说 coroutine ,还是 green thread...
    qi1070445109
        15
    qi1070445109  
       116 天前 via Android
    用 python 下载的时候,多线程总是跑不满带宽
    kenvix
        16
    kenvix  
       116 天前
    其他的别人都说了,我来补充下多进程的场景吧,通常使用多进程的目的是:
    1. 跨语言协作:当项目使用了多种不能在一个运行时一起运行的语言时
    2. 用效率为代价换取健壮性:适用于大型项目。使用多进程执行各个模块,某个模块跑飞时不至于整个程序全崩,可以很容易恢复
    3. 用效率为代价换取安全性:可以用于执行不是特别靠谱的代码,防止不靠谱代码炸了整个程序
    kenvix
        17
    kenvix  
       116 天前
    @kenvix #16 2 3 就是 Chrome 的做法,每个标签页各自独立,崩溃不会影响其他标签
    4. Python 这类有 GIL 的语言,多进程是为了执行 CPU 密集任务,本质是把多进程当多线程用
    kenvix
        18
    kenvix  
       116 天前
    @shrugginG #3 多进程的应用还是非常多的,目前 Windows Explorer 、Windows Service Host 实际上都是在从多线程往多进程改,为了健壮和安全
    Jony4Fun
        19
    Jony4Fun  
       116 天前
    刚刚看到这篇 libevent 讲异步 IO 的,OP 要不一起看看,虽然是 tiny introduction
    https://libevent.org/libevent-book/01_intro.html
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2203 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 16:12 · PVG 00:12 · LAX 09:12 · JFK 12:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.