我最近在学习和阅读很多关于Flow和 Kotlin 协程的内容。但是我仍然对什么时候应该使用Flow以及什么时候应该使用Channel.
一开始看起来更简单。使用热数据流?Channel. 冷的?Flows. 如果您需要从多个地方收听数据流,情况也是如此;如果是这样的话Channel是选择去。还有很多例子和问题。
但是最近FlowChannels引入了大量方法和类,这些方法和类鼓励使用Flow,转换Channels成哪些设施Flows等等。随着每个 Kotlin 版本中出现所有这些新东西,我越来越困惑。所以问题是:
什么时候应该使用Channel,什么时候应该使用Flow?
我正在研究一个并发的Go库,我偶然发现了结果相似的goroutine之间的两种不同的同步模式:
使用Waitgroup
var wg sync.WaitGroup
func main() {
words := []string{ "foo", "bar", "baz" }
for _, word := range words {
wg.Add(1)
go func(word string) {
time.Sleep(1 * time.Second)
defer wg.Done()
fmt.Println(word)
}(word)
}
// do concurrent things here
// blocks/waits for waitgroup
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)
使用频道
func main() {
words = []string{ "foo", "bar", "baz" }
done := make(chan bool)
defer close(done)
for _, word := range words {
go func(word string) {
time.Sleep(1 * time.Second)
fmt.Println(word)
done <- …Run Code Online (Sandbox Code Playgroud) 我希望在两个通道上进行常规监听,当两个通道都耗尽时阻塞.但是,如果两个通道都包含数据,我希望在处理另一个通道之前将其耗尽.
在下面的工作示例中,我希望out在exit处理之前将所有内容都耗尽.我使用select没有任何优先顺序的-statement.我如何解决问题,在退出之前处理所有10个输出值?
package main
import "fmt"
func sender(out chan int, exit chan bool){
for i := 1; i <= 10; i++ {
out <- i
}
exit <- true
}
func main(){
out := make(chan int, 10)
exit := make(chan bool)
go sender(out, exit)
L:
for {
select {
case i := <-out:
fmt.Printf("Value: %d\n", i)
case <-exit:
fmt.Println("Exiting")
break L
}
}
fmt.Println("Did we get all 10? Most likely not")
}
Run Code Online (Sandbox Code Playgroud) 如何检查频道是否有值供我阅读?
我不想在阅读频道时阻止.我想看看它是否有价值.如果它有一个,我会读它.如果它还没有(还),我会做其他事情,稍后再回来查看.
谢谢!
我有一个Node.js Web服务器在顶部运行套接字服务器,它是使用Socket.io创建的.基本上,这是有效的.
我现在想要实现的是连接的客户端是成组聚集的.因此,可能有一些客户构成组A和组成组B的其他一些客户.他们应通过寻址特定URL来选择他们所属的组,localhost:3000/A或者localhost:3000/B.
在Socket.io中,我现在想要向组A中的所有客户端或组B中的所有客户端或所有客户端发送消息,而不查看他们的组.
它基本上就像与房间聊天一样,无论他在哪个房间,您都可以为特定房间内的所有客户或任何客户提供消息.
使用Socket.io设计这样一个系统的最佳方法是什么?
到目前为止,我一直在尝试使用命名空间,这基本上可以用于创建组A和B,但是我失去了向所有客户端发送消息的能力,无论他们在哪个房间.至少我不知道该怎么做这个.
我该如何塑造这个?我应该寻找哪些合适的术语?
更新:根据@sdedelbrock的答案,我可以使用命名空间或房间:
io.sockets是一个快捷方式io.of(''),当然它不再与命名空间匹配.简而言之:为什么同一个(?)想法有两个概念?
Golang新手在这里.
两者之间是否存在功能差异?
func randomNumberGenerator() <-chan int {
Run Code Online (Sandbox Code Playgroud)
和
func randomNumberGenerator() chan int {
Run Code Online (Sandbox Code Playgroud)
我尝试过使用它们,它们似乎对我很好.
我已经看过Rob Pike(Go创建者之一)在Google IO 2012的Go Concurrency Patterns演讲中使用的前者.我也看到它在Go的官方网站上使用过.为什么可以省略它时添加2个额外字符("< - ")?我已经尝试在网上寻找差异,但找不到它.
我最近开始阅读有关Go编程语言的内容,我发现通道变量是一个非常吸引人的概念.是否可以在Haskell中模拟相同的概念?也许有一个数据类型Channel a和一个monad结构来启用可变状态和函数,就像关键字一样go.
我在并发编程方面不是很擅长,而在Haskell中这样简单的通道传递机制会让我的生活更轻松.
编辑
人们让我澄清了我对转换为Haskell感兴趣的Go模式.所以Go的通道变量是第一类的,可以传递并由函数返回.我可以读取和写入这些通道,因此可以在可以并发运行的例程之间轻松进行通信.Go还有一个go关键字,根据语言规范同时启动函数执行作为独立线程,并继续执行代码而无需等待.
我感兴趣的是确切的模式是这样的(Go的语法很奇怪 - 变量由varName的VARTYPE而不是通常的倒方式声明的 - 但我认为这是可读的):
func generateStep(ch chan int) {
//ch is a variable of type chan int, which is a channel that comunicate integers
for {
ch <- randomInteger() //just sends random integers in the channel
}
func filter(input, output chan int) {
state int
for {
step <- input //reads an int from the input channel
newstate := update(state, step) //update the variable with some update function …Run Code Online (Sandbox Code Playgroud) 我搜索redis命令列表.我找不到命令来获取redis pub/sub中的所有可用频道.在流星服务器中,等效命令是LISTCHANNELS,它列出了所有已知信道,每个信道上存储的消息数和当前用户数.
我有一个需要定期了解可用频道的cron.redis是否有本机命令?或者我需要找到一种方法来自己实现它?
有没有办法从该频道外部向频道广播消息?
也许是这样的Channel.broadcast topic, event, data?
我在这里看到了类似的东西但是Phoenix.Channel.broadcast/3(截至今天)的最终版本采用了一个隐含通道和主题的套接字.