为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 和并发/并行

Golang 和并发/并行

Go
宝慕林4294392 2021-10-18 16:59:44
我正在深入 Golang 并且有一个问题,我已经研究了几天,我似乎无法掌握 goroutines 的概念以及它们是如何使用的。基本上我是,试图生成数百万条随机记录。我有生成随机数据的函数,并将创建一个包含这些数据的巨大 .CSV 文件。我的问题是是否有可能使这个并发并加快速度?我的代码基本上是生成一个随机字符串,将字符串写入文件最多 N 次(其中 N 是您想要的任何内容)。我的问题是是否可以同时执行此操作以减少执行时间。似乎无论我如何处理这个问题,我仍然得到相同的基准测试,就好像我没有使用 go 例程一样。这是我到目前为止所拥有的示例:func worker(c chan string) {        for {                c <- /* Generate random data using other functions here */        }        close(c)}func writer(s string) {        csvfile.WriteString(s)}func main(){        receive := make(chan string)    for i := 0; i < 100; i++ {        go worker(receive)    }    for i := 0; i < 10000; i++ {        go writer(<-receive)    }}在我生成数据的地方,我使用了大量来自https://github.com/Pallinder/go-randomdata的函数调用。你认为这可能是我一直在失去的地方吗?任何帮助,将不胜感激。
查看完整描述

2 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

我认为您不应该在这里尝试使用 go 例程。文件写入几乎总是原子的,您希望使写入文件的机制并发......这将需要一个复杂的锁定机制,由于写入本身仍然是原子的,因此最终可能不会提高应用程序性能。


如果数据生成阻碍了您的程序,那么将这些工作拆分到 go 例程中并从您获取所有数据的地方开始编写是有意义的。但


for i := 0; i < 100; i++ {

    go worker(receive)

}


for {

    select {

    case item := <-receive:

         writer(item)

    case <-abort:

         cleanUp()

         return

    }

}

您不能在从通道接收并无休止地调用函数时循环一些 int ……但是您可以在选择中从通道接收。或者只是通过这样做item := <-recieve会阻塞,直到读取一项。在我上面的示例中,我提供了一些伪代码来更多地演示在这种情况下您的设计应该是什么。您需要一个中止通道,以便在您想停止应用程序时可以退出 go 例程。它可能应该完成对文件的写入,然后在返回之前关闭它。


查看完整回答
反对 回复 2021-10-18
?
智慧大石

TA贡献1946条经验 获得超3个赞

尝试缓冲您的频道

receive := make(chan string, 1000)

写入速度受您的磁盘限制,因此您只能通过并发写入来提供帮助,而从您所说的并发生成数据来看,它也无济于事。

并发不是解决任何缓慢问题的方法,要么接受您处于极限状态,要么进行优化。


查看完整回答
反对 回复 2021-10-18
  • 2 回答
  • 0 关注
  • 175 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信