Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Concurrency 我应该在golang中何时使用并发?_Concurrency_Go - Fatal编程技术网

Concurrency 我应该在golang中何时使用并发?

Concurrency 我应该在golang中何时使用并发?,concurrency,go,Concurrency,Go,那么,除了处理多个服务器请求之外,还有其他与并发相关的时间吗?我问这个问题是因为它是围棋的固有功能,如果我不使用它,我会感到浪费,但我几乎找不到它的用途。我还不是围棋专家,但我想说: 只要是最容易做到的 Go中并发模型的美妙之处在于,它从根本上讲并不是一个多核架构,在通常情况下,它是一个多线程的范例,不仅适合于多核架构,也适合于分布式系统架构 你不必为多个goroutine做特别的安排,它们就可以和谐地一起工作 这是一个自然并发算法的示例-我想将多个通道合并为一个。一旦所有的输入通道都用尽,我想

那么,除了处理多个服务器请求之外,还有其他与并发相关的时间吗?我问这个问题是因为它是围棋的固有功能,如果我不使用它,我会感到浪费,但我几乎找不到它的用途。

我还不是围棋专家,但我想说:

只要是最容易做到的

Go中并发模型的美妙之处在于,它从根本上讲并不是一个多核架构,在通常情况下,它是一个多线程的范例,不仅适合于多核架构,也适合于分布式系统架构

你不必为多个goroutine做特别的安排,它们就可以和谐地一起工作

这是一个自然并发算法的示例-我想将多个通道合并为一个。一旦所有的输入通道都用尽,我想关闭输出通道

使用并发更简单——事实上,它看起来甚至不像并发——它看起来几乎是过程性的

/*
  Multiplex a number of channels into one.
*/
func Mux(channels []chan big.Int) chan big.Int {
    // Count down as each channel closes. When hits zero - close ch.
    var wg sync.WaitGroup
    wg.Add(len(channels))
    // The channel to output to.
    ch := make(chan big.Int, len(channels))

    // Make one go per channel.
    for _, c := range channels {
        go func(c <-chan big.Int) {
            // Pump it.
            for x := range c {
                ch <- x
            }
            // It closed.
            wg.Done()
        }(c)
    }
    // Close the channel when the pumping is finished.
    go func() {
        // Wait for everyone to be done.
        wg.Wait()
        // Close.
        close(ch)
    }()
    return ch
}
我在这里对并发性的唯一让步是使用sync.WaitGroup作为并发计数的计数器


请注意,这不仅仅是我自己的工作——我在这方面得到了很多帮助。

这是Go的发明者之一Rob Pike使用并发的一个很好的例子,因为它更容易表达问题的解决方案:

概括一下,任何生产者-消费者问题都自然适合使用通道将生产者的输出传递给消费者的2个goroutine

并发的另一个很好的用途是与多个输入/输出源(磁盘、网络、终端等)交互。。当结果来自这些来源时,您的程序应该能够醒来并执行一些工作。可以通过一个线程和一个系统调用(如poll2或select2)来实现这一点。当你的线程醒来时,它必须找出哪个结果出现了,找到它在相关任务中的中断位置,然后从那里继续。你需要写很多代码


使用每个任务一个goroutine编写代码要容易得多。然后,该任务的状态在goroutine中被隐式捕获,从它停止的地方开始只需唤醒并运行即可。

也不是Go的专家,因此我的一些方法可能不规范,但到目前为止,我发现并发非常有用:

在等待网络请求、磁盘I/O或数据库查询完成时执行操作 更快地执行分治算法 由于goroutine是函数,而函数是Go中的头等公民,所以可以将它们作为变量传递。当您的程序有许多自治部分时,这很方便。例如,我正在模拟一个城市的交通系统。每辆车都有自己的goroutine,它们通过通道与十字路口和其他车辆进行通信。每个人都有自己的事情。 跨不同设备的同步I/O操作 使用并发在图像中的一组点上执行Dijkstra算法来绘制智能剪刀线-每个点一个goroutine使该实现大大加快。 使用并发性同时跨包运行测试,以便在使用调试时更快地响应更改。作为一个固有的好处,这会给测试序列增加一些伪随机性,从而使测试结果真正一致。 并发性可以被读取:有时是有用的,但当您的操作可以彼此独立运行,但在其他情况下会按顺序运行时,并不一定总是有用的。即使这些操作依赖于某些点上来自其他goroutine的数据或某种信号,您也可以通过通道进行通信


有关这些问题的一些灵感和重要区别,以及一些有趣的地鼠图片,请参见。

我的2美分。。。如果您仅在并发上下文中考虑通道/goroutines,那么您就错过了机会

虽然go不是一种对象语言或严格意义上的函数语言,但它确实允许您从这两种语言中获取设计功能并应用它们

面向对象设计的基本原则之一是单一责任 道德原则应用这一原则迫使您从消息的角度来考虑设计,而不是复杂的对象行为。这些相同的设计约束可用于go,以允许您开始考虑连接单用途功能的通道上的消息

这只是一个例子,但如果你开始这样想,你会看到更多