我正在尝试做一些事情:
type Feed struct { title, descr, link string published time.Time } func main() { ar := make([]Feed, 0) for i := 0; i < 3; i++ { f: = new(Feed) // do some stuff with feed ar = append(ar, *f) } ch := make(chan Feed, 3) for _, i := range ar { go process(i, ch) } r :=0 for i := range ch { fmt.Println(i) r++ if r == 3 { close(ch) } } } func process(i Feed, ch chan Feed) { // do some stuff ch <- i }
似乎ar没有必要,但是如果将其删除,则最后一个范围将永远存在。我做错了什么?
ar
另一个问题是-使用Go例程的这种方式正确吗?
这是生产者- 消费者类型的示例。我只使用WaitGrouphere,这样主goroutine不会立即退出。从理论上讲,您的应用程序可以等待,或者在此期间做一些其他有趣的事情。
WaitGroup
请注意,您还可以使用c := make(chan(*Feed, n))其中n要缓冲编号的缓冲通道。请注意,在典型的生产者- 消费者方案中,有时每个作业分配了很多资源。因此,根据需要,您可以仅缓冲其中的一些缓冲,也可以全部缓冲。
c := make(chan(*Feed, n))
n
如果没有缓冲通道,它将充当goroutine之间的同步。生产者在c <-等待消费者<- c交接时阻塞,因此每个例程中只有一个例程一次执行这些行。
c <-
<- c
编辑 我在打印“开始”之前添加了一个暂停,以使输出不太同步。以前总是输出:
created started created started ...
https://play.golang.org/p/FmWqegr-CR
package main import ( "fmt" "math/rand" "sync" "time" ) type Feed struct { title, descr, link string published time.Time } func CreateFeed() *Feed { r := rand.Int() % 500 time.Sleep(1000 + time.Duration(r)*time.Millisecond) fmt.Println("Feed created") return &Feed{ published: time.Now(), } } func UseFeed(f *Feed) { time.Sleep(100 * time.Millisecond) fmt.Println("Feed started") time.Sleep(1600 * time.Millisecond) fmt.Printf("Feed consumed: %s\n", f.published) } func main() { numFeeds := 10 var wg sync.WaitGroup wg.Add(10) c := make(chan (*Feed)) for i := 0; i < numFeeds; i++ { go func() { c <- CreateFeed() }() } for i := 0; i < numFeeds; i++ { go func() { f := <-c UseFeed(f) wg.Done() }() } wg.Wait() }
我希望这是您想要的。