2017-04-23 37 views
1

我想做一个循环的goroutines,它需要一个接收字符串的通道,并且每次收到它时都应该将该值附加到另一个字符串。只有在所有程序结束时(程序计数应该是通过的list的长度),如果代码继续运行。goroutine,需要一个通道接收器,并将字符串发送到通道

我下面的示例似乎并没有将strReceiver通道中的值附加到str上,因为str永远不会被修改。

任何人都知道什么是错的?

func appendToStr(str string, list []string, origin *url.URL) { 
    var currProc int32 = 0; 
    var maxProc int32 = int32(len(list)) 

    var strReceiver := make(chan string, len(list)) 
    for _, item := range list { 
     go func() { 
      doAsyncAndIncrement(item, strReceiver, &currProc) 
      str += <-strReceiver 
     }() 
    } 

    for { 
     if atomic.LoadInt32(&currProc) <= maxProc { 
      break; 
     } 
    } 

    // continue on using 'str' which now contains the append values from the 'strReceiver' channel 
} 

func doAsyncAndIncrement(item string, receiver chan<- string, count *int32) { 
    defer atomic.AddInt32(count, 1) 

    var val string 
    // do something with 'item' and set 'val'... 

    receiver <- val 
} 
+1

对不起,这是我的错误。异步功能应该确实在接收器中。我更新了我的代码。 – Lansana

+0

'atomic.LoadInt32(&currProc)<= maxProc'这个条件不应该被否定吗? currProc会在第一次迭代时破解,甚至在产卵的goroutine有机会运行之前 – nvartolomei

回答

1

你的代码的一个问题是,围绕你的去例程调用的闭包太大了。

for _, item := range list { 
    go func() { 
     doAsyncAndIncrement(item, strReceiver, &currProc) 
     str += <-strReceiver 
    }() 
} 

item的作用范围是for循环,而不是在你的goroutine匿名函数,所以当你射击关闭N.够程,你item变量同时被一个更新的循环。要解决这个问题,请将变量明确地传递给您的goroutine,以避免使用闭包:

for _, item := range list { 
    go func(item string) { 
     doAsyncAndIncrement(item, strReceiver, &currProc) 
     str += <-strReceiver 
    }(item) 
} 
相关问题