恐慌:同步:负WaitGroup计数器

sin*_*Gob 4 concurrency go

我的目标是使用 goroutines 和 channel,我想学习如何在不同的 goroutines 之间进行通信,我想避免死锁。我设法使用sync.WaitGroup,它工作得很好。

但是我收到一个错误说

1恐慌:同步:负WaitGroup计数器

goroutine 19 [正在运行]:

这个程序的目标很简单。

  1. 创建开发人员
  2. 指派他/她创建一个网站
  3. 取决于网站的数量
  4. 网站完成后,将其附加到数组
  5. 让有 20 个网站和 5 个开发人员
  6. 每个开发人员将创建 4 个网站并将其附加到网站数组中
  7. 我想同时进行,以便其他开发人员不必等待

编码:

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 <- 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 := <-developerCreatedc
  for i := 0; i <= 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 := &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 <= numberOfDevelopers; i++ {
    go func(producerNumber int) {
        hireDeveloper(wg, producerNumber, developerCreatedC, 
        developers)
    }(i)
   }

  wg.Add(1)
  for i := 1; i <= websitePerDeveloper; i++ {
    createComputer(wg, developerCreatedC, 5, websites)
  }

  wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)

游乐场 https://play.golang.org/p/QSOv5jp3T94

行为有时有点,一个开发者创建了 4 个以上的网站,即使它应该只创建 4 个

谢谢

nig*_*204 7

wg.Add()应该等于你正在运行的 goroutine 的数量。也createComputer(wg, developerCreatedC, websitePerDeveloper, websites)应该是每个开发人员的基础。

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 <- 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 := <-developerCreatedc
    for i := 0; i <= websitePerComputer; i++ {
        fmt.Println("Delegate", d.name, "to set the time to start building the website")
        d.setTimeForWebsite = time.Now()
        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 := &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

    for i := 1; i <= numberOfDevelopers; i++ {
        // add the sync
        wg.Add(1)
        go func(producerNumber int) {
            hireDeveloper(wg, producerNumber, developerCreatedC, developers)
        }(i)

        wg.Add(1)
        go createComputer(wg, developerCreatedC, websitePerDeveloper, websites)
    }

    wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)