go - Goroutines blocked by for loop? -


i have following code implements worker queue:

package main  import (     "fmt"     "net/http"     "io"     "time" )  var (     linkqueue chan link     scraperqueue chan chan link )  func cycledirectory(page int) {     linkqueue <- link{name: "asd"} }  type link struct {     name string }  func (s scraper) start() {     fmt.println("started")     go func() {         {             s.scraperqueue <- s.link             select {             case link := <-s.link:                 fmt.println(fmt.sprintf("%v", s.id) + ": received " + link.name)             case <-s.quitchan:                 fmt.println("closed")                 return             }         }     }() }  func (s scraper) stop() {     go func() {         s.quitchan <- true     }() }  type scraper struct {     id int     link chan link     scraperqueue chan chan link     quitchan chan bool }  func initscraper(id int, scraperqueue chan chan link) scraper {     return scraper {         id: id,         link: make(chan link),         scraperqueue: scraperqueue,         quitchan: make(chan bool),     } }  func helloserver(w http.responsewriter, req *http.request) {     io.writestring(w, "hello, world!\n") }  func main() {     linkqueue = make(chan link, 2000)      numscrapers := 2      scraperqueue = make(chan chan link, numscrapers)      := 0; < numscrapers; i++ {         s := initscraper(i+1, scraperqueue)         s.start()     }      go func() {         {             select {             case link := <-linkqueue:                 go func() {                     scraper := <-scraperqueue                     scraper <- link                 }()             }         }     }()      cycledirectory(1)      // time.sleep(1 * time.millisecond)      {         // select {         // }     }      // http.handlefunc("/hello", helloserver)      // http.listenandserve(":12345", nil) } 

running code using loop containing if statement (or nothing inside), scraper not print received message. blocking using listenandserve function net/http, prints received message. blocking using sleep 1 ms, receive message. , putting select statement in loop, receive message.

why loop without select statement not allowing execution of message sending in worker queues, , how go handling this. need if statement in loop check if work has been done can exit loop , end program.

update

amd's suggestion solution problem. here updated code using sync.waitgroup package main

import (     "fmt"     "sync" )  var (     linkqueue chan link     scraperqueue chan chan link     wg sync.waitgroup )  func cycledirectory(page int) {     wg.add(1)     linkqueue <- link{name: "asd"} }  type link struct {     name string }  func (s scraper) start() {     fmt.println("started")     go func() {         {             s.scraperqueue <- s.link             select {             case link := <-s.link:                 scrape(s.id, link.name)                 s.stop()             case <-s.quitchan:                 fmt.println("closed")                 wg.done()                 return             }         }     }() }  func (s scraper) stop() {     go func() {         s.quitchan <- true     }() }  type scraper struct {     id int     link chan link     scraperqueue chan chan link     quitchan chan bool }  func scrape(id int, name string) {     fmt.println(fmt.sprintf("%v", id) + ": received " + name) }  func initscraper(id int, scraperqueue chan chan link) scraper {     return scraper {         id: id,         link: make(chan link),         scraperqueue: scraperqueue,         quitchan: make(chan bool),     } }  func main() {     linkqueue = make(chan link, 2000)      numscrapers := 2      scraperqueue = make(chan chan link, numscrapers)      := 0; < numscrapers; i++ {         s := initscraper(i+1, scraperqueue)         s.start()     }      go func() {         {             select {             case link := <-linkqueue:                 go func() {                     scraper := <-scraperqueue                     scraper <- link                 }()             }         }     }()      cycledirectory(1)      wg.wait()      fmt.println("done") } 

you may use sync.waitgroup stop program exiting until work done.
try on the go playground:

package main  import (     "fmt"     "sync"     "time" )  var (     wg sync.waitgroup )  func main() {     wg.add(1)     go func() {         defer wg.done()         time.sleep(2 * time.second)     }()      fmt.println("wait...")     wg.wait()     fmt.println("done.") } 

Comments

Popular posts from this blog

unity3d - Rotate an object to face an opposite direction -

angular - Is it possible to get native element for formControl? -

javascript - Why jQuery Select box change event is now working? -