
1 mlyy Sep 2, 2017 via iPhone coroutine 不能完全等于单线程。因为 await 本质相当于 yield,出让当前执行栈的执行权(防止阻塞)。也就是说,同一时刻内存中存在多个,不一定相互重叠的执行栈。说白了,多线程的调度是操作系统的 scheduler,而 coroutine 的调度是你的代码。 |
2 mlyy Sep 2, 2017 via iPhone 至于 queue 为何"正确"(undefined behavior),不如贴出你的测试代码,看看是否真的实现了 await 操作。 |
3 NoAnyLove Sep 2, 2017 具体事情具体讨论,并没有说协程就一定不加锁,协程本身的某些功能实现也是通过线程池实现的;就算没有用到其他线程,假如一个操作需要连续性地完成,那么也是需要借助锁的概念。asyncio 和 gevent 库中都有实现 threading 下的一些同步机制,比如 Lock、Semaphore 等,虽然和 threading 的底层的实现不同,但是同样起到了保证一些操作顺序、不会被打断地执行。 另外,queue 自带锁 |
4 misaka19000 Sep 2, 2017 > 协程是用户态相互协作的线程 你看,本质上还是线程,所以还是可能存在竞争条件,所以需要加锁 |
5 lolizeppelin Sep 2, 2017 谁和你说不用加锁的... |
6 oneoo Sep 3, 2017 协程都是平等、并行的多个任务,它本身并不是多线程,每次运行的都是某个代码片段,go 是通过多线程来执行这些代码片段,才让大家误解。 但协程的代码里面有可能会调用到底层的 C 代码,如很多库就是 C 写的,如果这个库没做好多线程的锁操作,就会出现帖子说的事。这也说明这个库实现有严重问题 有兴趣可以去看看 OpenResty、Nginx+Lua,也是协程的世界。但这个世界里连“锁”的任何操作方法都没暴露给开发者,就是因为协程本身是不需要锁的。底层的事情就应该完整隐藏起来,这样使用者才不会遇到这种摸不着头脑的事 |
7 oaoouo Sep 4, 2017 补充一下, Python 的一些数据结构是线程安全的(比如 collections 模块的 deque 结构), 使用这些结构多线程就可以不用加锁. |