gpt4 book ai didi

Python 相当于 Golang 在 channel 上的选择

转载 作者:IT老高 更新时间:2023-10-28 13:03:47 51 4
gpt4 key购买 nike

Go 有一个适用于 channel 的 select 语句。来自文档:

The select statement lets a goroutine wait on multiple communication operations.

A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.

是否有以下代码的 Python 等效项:

package main

import "fmt"

func main() {
c1 := make(chan int)
c2 := make(chan int)
quit := make(chan int)

go func() {
for i := 0; i < 10; i++ {
c1 <- i
}
quit <- 0
}()

go func() {
for i := 0; i < 2; i++ {
c2 <- i
}
}()

for {
select {
case <-c1:
fmt.Println("Received value from c1")
case <-c2:
fmt.Println("Received value from c2")
case <-quit:
fmt.Println("quit")
return
}
}
}

这个程序的输出:

Received value from c1
Received value from c1
Received value from c2
Received value from c1
Received value from c2
Received value from c1
Received value from c1
Received value from c1
Received value from c1
Received value from c1
Received value from c1
Received value from c1
quit

最佳答案

这是一个非常直接的翻译,但“如果多个已准备好,则选择哪个”部分的工作方式不同 - 它只是采用首先出现的内容。这也类似于使用 gomaxprocs(1) 运行您的代码。

import threading
import Queue

def main():
c1 = Queue.Queue(maxsize=0)
c2 = Queue.Queue(maxsize=0)
quit = Queue.Queue(maxsize=0)

def func1():
for i in range(10):
c1.put(i)
quit.put(0)

threading.Thread(target=func1).start()

def func2():
for i in range(2):
c2.put(i)

threading.Thread(target=func2).start()

combined = Queue.Queue(maxsize=0)

def listen_and_forward(queue):
while True:
combined.put((queue, queue.get()))

t = threading.Thread(target=listen_and_forward, args=(c1,))
t.daemon = True
t.start()
t = threading.Thread(target=listen_and_forward, args=(c2,))
t.daemon = True
t.start()
t = threading.Thread(target=listen_and_forward, args=(quit,))
t.daemon = True
t.start()

while True:
which, message = combined.get()
if which is c1:
print 'Received value from c1'
elif which is c2:
print 'Received value from c2'
elif which is quit:
print 'Received value from quit'
return
main()

基本的变化是使用组合消息的线程来模拟选择。如果你打算经常使用这种模式,你可能会写一些选择代码:

import threading
import Queue

def select(*queues):
combined = Queue.Queue(maxsize=0)
def listen_and_forward(queue):
while True:
combined.put((queue, queue.get()))
for queue in queues:
t = threading.Thread(target=listen_and_forward, args=(queue,))
t.daemon = True
t.start()
while True:
yield combined.get()

def main():

c1 = Queue.Queue(maxsize=0)
c2 = Queue.Queue(maxsize=0)
quit = Queue.Queue(maxsize=0)

def func1():
for i in range(10):
c1.put(i)
quit.put(0)

threading.Thread(target=func1).start()

def func2():
for i in range(2):
c2.put(i)

threading.Thread(target=func2).start()

for which, msg in select(c1, c2, quit):
if which is c1:
print 'Received value from c1'
elif which is c2:
print 'Received value from c2'
elif which is quit:
print 'Received value from quit'
return
main()

但是……

请注意,这个选择并不完全是 go 选择,尽管它对您的程序无关紧要 - goroutine 可以在 channel 上发送结果,该结果将在选择中排队并丢失,如果我们不总是遍历选择以完成!

关于Python 相当于 Golang 在 channel 上的选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19130986/

51 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com