V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
lenqu
V2EX  ›  Python

Python 的线程处理和协程有区别么?线程库 Eventlet、Gevent 的实现是否可以做到多个线程同时并发呢?

  •  
  •   lenqu · 2019-12-28 11:36:37 +08:00 · 5650 次点击
    这是一个创建于 1552 天前的主题,其中的信息可能已经有所发展或是发生改变。

    求大佬们给个详细的理解

    16 条回复    2020-01-09 21:20:34 +08:00
    676529483
        1
    676529483  
       2019-12-28 11:45:03 +08:00
    这个。。。你的基础差的有点多,先学习下同步异步线程协程等的概念把
    wuwukai007
        2
    wuwukai007  
       2019-12-28 11:48:15 +08:00 via Android
    找一个爬虫异步版照着敲一遍感受一下
    lenqu
        3
    lenqu  
    OP
       2019-12-28 12:03:46 +08:00
    python 的线程,python 的线程不是标准线程,在 python 中,一个进程内的多个线程只能使用一个 CPU。

    如果使用 gevent 包装后的线程,程序员就不必承担调度的责任,而 python 的线程本身就没有使用多 CPU 的能力,那么,用 gevent 包装后的线程,取代 python 的内置线程,不是只有避免无意义的调度,提高性能的好处,而没有什么坏处了吗?

    答案是否定的。举一个例子,有一个 GUI 程序,上面有两个按钮,一个 运算 一个 取消 ,点击运算,会有一个运算线程启动,不停的运算,点击取消,会取消这个线程,如果使用 python 的内置线程或者标准线程,都是没有问题的,即便运算线程不停的运算,调度器仍然会给 GUI 线程分配时间片,用户可以点击取消,然而,如果使用 gevent 包装后的线程就完蛋了,一旦运算开始,GUI 就会失去相应,因为那个运算线程(协程)霸着 CPU 不让位。不单是 GUI,所有和用户交互的程序都会有这个问题
    lenqu
        4
    lenqu  
    OP
       2019-12-28 12:05:09 +08:00
    1) 一个线程可以多个协程,一个进程也可以单独拥有多个协程,这样 python 中则能使用多核 CPU。

    2) 线程进程都是同步机制,而协程则是异步

    3) 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态
    lenqu
        5
    lenqu  
    OP
       2019-12-28 12:07:18 +08:00   ❤️ 1
    2、多线程一般是使用 threading 库,完成一些 IO 密集型并发操作。多线程的优势是切换快,资源消耗低,但一个线程挂掉则会影响到所有线程,所以不够稳定。现实中使用线程池的场景会比较多,具体可参考 https://www.cnblogs.com/rianley/p/9076207.html

       3、协程一般是使用 gevent 库,当然这个库用起来比较麻烦,所以使用的并不是很多。相反,协程在 tornado 的运用就多得多了,使用协程让 tornado 做到单线程异步,据说还能解决 C10K 的问题。所以协程使用的地方最多的是在 web 应用上。

    总结一下就是 IO 密集型一般使用多线程或者多进程,CPU 密集型一般使用多进程,强调非阻塞异步并发的一般都是使用协程,当然有时候也是需要多进程线程池结合的,或者是其他组合方式。
    wzwwzw
        6
    wzwwzw  
       2019-12-28 12:10:12 +08:00
    看看线程,进程,协程,在看看 python 的 thread , multiprocessing, asyncio.
    misaka19000
        7
    misaka19000  
       2019-12-28 12:13:51 +08:00   ❤️ 2
    so1n
        8
    so1n  
       2019-12-28 12:23:48 +08:00 via Android
    @lenqu python 的线程是标准线程,调用的是系统的线程
    so1n
        9
    so1n  
       2019-12-28 12:25:16 +08:00 via Android
    @lenqu 进程线程也可以异步……
    jimages
        10
    jimages  
       2019-12-28 12:26:35 +08:00   ❤️ 2
    从概念上讲,线程和协程是有区别的,理解为线程可以并行,协程不能并行。但是囿于 CPython 的具体实现问题( GIL )上,线程和协程在某种程度上是一致的。
    线程也就是有多个执行流,由操作系统负责调度执行流,由于执行流的切换是由操作系统负责的,所以对于编程者来说是完全透明的,无感知的(除去同步问题)。同时呢,由于执行流的调度是有操作系统负责的,在 SMP 上可以实现并行运行,也就是两个线程同时运行。
    但是协程也是有多个执行流,但是这个执行流是由用户来负责的,所以编程者需要大量处理协切换的问题。同时呢,由于协程是在用户的控制下进行切换。对操作系统来说,这只是一个线程。所以在 SMP 上无法享受到多线程的并发优势。
    为什么在 Python 上大家一般推崇协程而不是线程呢?
    线程的切换在操作系统的调度是,某一个线程运行了一段时间之后(可能是几十毫秒),这个时候就会发生调度切换。去运行其他的线程,这种频繁的线程切换实际上也是有开销的,可能会有几百个时钟周期。而这种线程切换是周期性的。所以总体来说开销还是蛮大的。
    但是对于协程来说,由于协程的切换是用户控制的,那么也就是说,少去了很多不必要的线程切换,因为用户自己控制线程切换时,大概率是真的有必要切换。所以比操作系统切换来说,开销更少了,操作系统不需要再进行周期性的切换了。
    youngce
        11
    youngce  
       2019-12-28 14:06:38 +08:00
    协程的话 gevent 也已经被 asyncio 替代了,毕竟后者是标准库,而且写起来也稍微舒服一些。
    ManjusakaL
        12
    ManjusakaL  
       2019-12-28 15:14:50 +08:00
    看了下,,槽点太多一下不知道从什么地方讲起。。。
    Courstick
        13
    Courstick  
       2019-12-28 15:31:31 +08:00
    w
    lenqu
        14
    lenqu  
    OP
       2019-12-28 16:44:44 +08:00
    @ManjusakaL 讲一下,大佬 o
    haozhang
        15
    haozhang  
       2019-12-29 09:15:41 +08:00 via Android
    1.所谓的“多个线程同时并发”其实就是并行,你可以搜索下并行 parallel 和并发 concurrency 的区别
    2.进程线程是操作系统进行调度的,你无法决定哪个特定时间点运行哪个进程或者线程
    3.协程是程序自行调度的,但凡是协程那么肯定已经预先写好了调度的代码,比如说 go 的协程,go 里面就已经写好了调度的逻辑代码。
    4.是否能够做到并行?能的,只要没有 GIL 全局解释器锁,那么就可以并行。
    cominghome
        16
    cominghome  
       2020-01-09 21:20:34 +08:00
    并发可以,并行不行
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1424 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 17:26 · PVG 01:26 · LAX 10:26 · JFK 13:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.