首页 > 解决方案 > 实现并发的不成功尝试

问题描述

我很难让 go 并发正常工作。我正在处理从 XML 数据源加载的数据。一旦我将数据加载到内存中,我就会遍历 XML 元素并执行操作。并发添加之前的代码已经过测试和功能,我认为它对并发添加没有任何影响。我在并发实现方面有 2 次失败的尝试,都具有不同的输出。我使用锁定是因为我不想进入竞争条件。

对于这个实现,它永远不会进入 goroutine。

    var mu sync.Mutex

    // length is 197K
    for i:=0;i<len(listings.Listings);i++{
      go func(){
         mu.Lock()

         // code execution (tested prior to adding concurrency and locking)

         mu.Unlock()     
      }()
    }

对于这个使用 waitGroups 的实现,a runtime out of memory occurs

    var mu sync.Mutex
    var wg sync.WaitGroup

    // length is 197K
    for i:=0;i<len(listings.Listings);i++{
       wg.Add(1)
       go func(){
           mu.Lock()

           // code execution (tested prior to adding concurrency and locking and wait group)      

           wg.Done()
           mu.Unlock()   
       }()
    }
    wg.Wait()

我不太确定发生了什么,可以使用一些帮助。

标签: goconcurrency

解决方案


  1. Mutex如果你想让它并发,你不需要在这里
  2. 197K goroitines 很多,尝试减少 goroutines 的数量。你可以通过创建 N 个 goroutines 来完成它,每个 goroutines 都在监听同一个频道。

https://play.golang.org/p/s4e0YyHdyPq

package main

import (
    "fmt"
    "sync"
)

type Listing struct{}

func main() {
    var (
        wg          sync.WaitGroup
        concurrency = 100
    )

    c := make(chan Listing)

    wg.Add(concurrency)
    for i := 0; i < concurrency; i++ {
        go func(ci <-chan Listing) {
            for l := range ci {
                // code, l is a single Listing
                fmt.Printf("%v", l)
            }
            wg.Done()
        }(c)
    }

    // replace with your var
    listings := []Listing{Listing{}}
    for _, l := range listings {
        c <- l
    }

    close(c)
    wg.Wait()
}

推荐阅读