title: panic: sync: negative WaitGroup counter
body: <p>My goal is to use goroutines and channel, i want to learn how to communicate between different goroutines and i want to avoid deadlock. I managed to use <code>sync.WaitGroup</code> and it is working just fine. </p>
  
  <p>However I received an error saying that </p>
  
  <blockquote>
    <p>1 panic: sync: negative WaitGroup counter</p>
    
    <p>goroutine 19 [running]:</p>
  </blockquote>
  
  <p><strong>The goal of this program is simple.</strong> </p>
  
  <ol>
  <li>Create a developer</li>
  <li>Assign him/her to create a website</li>
  <li>Depends on the number of the websites</li>
  <li>Once website is done then append it to the array</li>
  <li>Let there are 20 websites and 5 developers</li>
  <li>Each developer will take create 4 websites and append it to the websites array</li>
  <li>I want to do it concurrently so that other developers don't have to wait</li>
  </ol>
  
  <p><strong>The code:</strong></p>
  
  <pre><code>package main
  
  import (
    "fmt"
    "sync"
    "time"
  )
  
  type developer struct {
      name              string
      setTimeForWebsite time.Time
  }
  
  type website struct {
     owner   string
     created time.Time
  }
  
  var developers []developer
  var websites []website
  
  // A function to create a developer
   func hireDeveloper(wg *sync.WaitGroup, workNumber int, 
     developerCreatedc chan developer, devs []developer) {
     defer wg.Done()
     developerNumber := fmt.Sprintf("developer_%d", workNumber)
     d := developer{name: developerNumber}
     fmt.Println("Hired", d.name)
     developerCreatedc &lt;- d
   }
  
   // A function to create a website
    func createComputer(wg *sync.WaitGroup, developerCreatedc chan developer, websitePerComputer int, websites []website) {
    defer wg.Done()
     // Assign the developer to the website creation // N number of the website
    d := &lt;-developerCreatedc
    for i := 0; i &lt;= websitePerComputer; i++ {
      fmt.Println("Delegate", d.name, "to set the time to start 
      building the website")
      d.setTimeForWebsite = time.Now()
      fmt.Println(d.name, "Finish calculating to build the website", d.setTimeForWebsite)
      web := website{owner: d.name, created: d.setTimeForWebsite}
      websites = append(websites, web)
      fmt.Println(len(websites))
      time.Sleep(time.Second * 2)
      fmt.Println(d.name, "Created website at", web.created)
     }
  
    }
  
  func main() {
  
    // Make a channel for when developer is hired 
    developerCreatedC := make(chan developer)
    // create a sync group
    wg := &amp;sync.WaitGroup{}
    // Assume that number of websites are 20
    numberOfWebsites := 20
    // Assume that number of developers are 5
    numberOfDevelopers := 5
    // Divide the websites to 5 developers
    websitePerDeveloper := numberOfWebsites / numberOfDevelopers
    // add the sync
    wg.Add(1)
    for i := 1; i &lt;= numberOfDevelopers; i++ {
      go func(producerNumber int) {
          hireDeveloper(wg, producerNumber, developerCreatedC, 
          developers)
      }(i)
     }
  
    wg.Add(1)
    for i := 1; i &lt;= websitePerDeveloper; i++ {
      createComputer(wg, developerCreatedC, 5, websites)
    }
  
    wg.Wait()
  }
  </code></pre>
  
  <p>The playground
  <a href="https://play.golang.org/p/QSOv5jp3T94" rel="nofollow noreferrer">https://play.golang.org/p/QSOv5jp3T94</a></p>
  
  <p>The behaviour is a bit sometimes, one developer created more than 4 websites, even though it is supposed to create only 4</p>
  
  <p>Thanks</p>