What's issue with this goroutine code?


(Jameswang2015) #1

here is my code:

package main

import (
	"bufio"
	"fmt"
	"net/http"
	"time"
)

const (
	numberOfWorkers int = 3
	numberOfTasks int = 5
)

func worker(id int, url chan string, result chan bool){
	client := http.Client{
		Timeout: 5 * time.Second,
	}
	for receivedURL := range url{
		fmt.Printf("worker %d start on %s\n", id, receivedURL)
		resp, err := client.Get(receivedURL)
		if err != nil {
			resp.Body.Close()
			panic(err)
		}
		fmt.Println("response status:", resp.Status)
		scanner := bufio.NewScanner(resp.Body)
		for i := 0; scanner.Scan() && i < 5; i++ {
			fmt.Println(scanner.Text())
		}
		if err := scanner.Err(); err != nil {
			resp.Body.Close()
			panic(err)
		}
		fmt.Printf("worker %d Done with %s\n\n\n\n", id, receivedURL)
		resp.Body.Close()
		result <- true
	}

}

func main() {
	url := make(chan string)
	result := make(chan bool)
	urls := []string{
		"http://gobyexample.com",
		"http://att.com",
		"http://domaintools.com",
		"http://microsoft.com",
		"http://google.com",
	}
	for i := 0; i < numberOfWorkers; i++ {
		go worker(i, url, result)
	}
	for j := 0; j < numberOfTasks; j++ {
		url <- urls[j]
	}
	close(url)

	for t := 0; t < numberOfTasks; t++ {
		if <-result {
			fmt.Printf("get %d done", t)
		}
	}

}

here is output: it stuck (dead locked I think)

dth,minimum-scale=1,initial-scale=1" class="next-head"/><meta charSet="utf-8" class="next-head"/><meta charSet="utf-8" class="rennaissanceAEM64 next-head"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" class="next-head"/>
<meta name="viewport" content="initial-scale=1.0, width=device-width" class="next-head"/>
<meta name="keywords" content="att, at&amp;t, wireless, internet, tv, support, directv, phones, deals, prepaid, entertainment, bundles" class="next-head"/>
<meta name="description" content="Visit att.com to switch and save on phone plans, internet service, &amp; TV with premium entertainment! America&#x27;s best network is also the fastest." class="next-head"/>
worker 0 Done with http://att.com



response status: 200 OK
 

<!DOCTYPE html>
<html lang="en">
  <head>
worker 1 Done with http://domaintools.com



   

I couldn’t copy the entire output but basically the three workers get the first 3 jobs done, but no one can execute result <- true and then it get dead lock.
what causes this?


What's the issue with this code
(Norbert Melzer) #2

We had this yesterday. Since all channels are unbuffered, there is no reader available after all goroutines reached sending to result, as main still tries sending on jobs…