Golang和并发/并行

时间:2015-07-06 16:09:02

标签: go

我潜入Golang并遇到一个问题,我已经工作了几天,我似乎无法掌握go例程的概念以及如何使用它们。

基本上我是,试图产生数百万的随机记录。我有创建随机数据的函数,并将创建一个包含此数据的巨大.CSV文件。

我的问题是,是否有可能使这个并发并加快速度?

我的代码基本上是生成一个随机字符串,最多可以写入N次文件(其中N是你想要的)。

我的问题是,是否可以同时执行此操作以减少执行时间。似乎无论我如何解决这个问题,我仍然会得到相同的基准,就像我没有去常规那样做。

这是我目前的样本:

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 个答案:

答案 0 :(得分:1)

我不认为你应该尝试在这里使用常规程序。文件写入几乎总是原子的,你想要使写入文件的机制并发...这需要一个复杂的锁定机制,最终可能由于写入本身仍然是原子的而不能提高应用程序性能。 / p>

如果数据生成对你的程序产生了影响,那么将这项工作分解为go例程并从你获得所有数据的地方写下是有意义的。但是

for i := 0; i < 100; i++ {
    go worker(receive)
}

for {
    select {
    case item := <-receive:
         writer(item)
    case <-abort:
         cleanUp()
         return
    }
}

您无法在从频道接收并无休止地调用某个函数时循环播放某个int ...您可以通过select中的频道接收。或者只是通过执行item := <-recieve来阻止直到一个项目被读取。在上面的例子中,我提供了一些伪代码来演示在这种情况下你的设计应该是什么。您需要一个中止通道,以便在您想要停止应用程序时可以退出运行程序。它可能应该完成对文件的写入,然后在返回之前将其关闭。

答案 1 :(得分:0)

尝试buffering your channel

receive := make(chan string, 1000)

写入速度受到磁盘的限制,因此只能通过并发写入来帮助您,并且从您所知道的同时生成数据也无济于事。

并发不是任何缓慢的解决方案,要么接受你的极限,要么优化。