【问题标题】:Understand goless.select from the sample code从示例代码中理解 goless.select
【发布时间】:2015-07-17 01:59:07
【问题描述】:

我发现了 Goroutines 的 python 实现,https://goless.readthedocs.org/en/latest/ 并且正在玩

鉴于文档中的以下代码:

c1 = goless.chan()
c2 = goless.chan()

def func1():
    time.sleep(1)
    c1.send('one')
goless.go(func1)

def func2():
    time.sleep(2)
    c2.send('two')
goless.go(func2)

for i in range(2):
    case, val = goless.select([goless.rcase(c1), goless.rcase(c2)])
    print(val)

然后打印出来:

one
two

关于select 方法的文档

选择第一个准备好的案例。如果是默认情况 (goless.dcase) 存在,如果没有其他案例准备好则返回。如果 没有默认案例,也没有案例准备好,阻塞直到一个成为 准备好了。

所以我继续将sleep(1) 更改为sleep(3),如下所示:

c1 = goless.chan()
c2 = goless.chan()

def func1():
    time.sleep(3)
    c1.send('one')
goless.go(func1)

def func2():
    time.sleep(2)
    c2.send('two')
goless.go(func2)

for i in range(2):
    case, val = goless.select([goless.rcase(c1), goless.rcase(c2)])
    print(val)

我认为它会打印出来:

two
one

但它打印出来了:

one
two

这是为什么呢?

【问题讨论】:

  • 尝试在 goroutines 中休眠 2000 毫秒和 3000 毫秒。我认为结果将是二->一。
  • 按时间同步不是同步。我不知道为什么它不起作用,但你不应该睡觉来尝试建立一个发生前发生的保证——它不是确定性的。

标签: python go


【解决方案1】:

由于没有答案,所以我去挖掘项目 repo,在这里发现了一个类似的问题:

https://github.com/rgalanakis/goless/issues/42

最值得注意的:

使用 time.sleep 只是暂停当前线程。它不会在协程之间进行任何切换。对于 Stackless(或 goless.backend.yield),您必须使用 gevent.sleep 或类似机制。

所以我似乎误解了 goless 会创建不同的线程,但我错了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多