golang异步缓冲的通道挂起

时间:2019-06-11 18:39:45

标签: go

作为第一个项目,我决定编写一个简单的异步网络浏览器。我的想法是要有一个任务队列和一组“解决”任务的工人。在编写程序时遇到了一个问题。

以下代码挂起:

    <div onmouseover="writeText2('the div works fine')">
      MOUSE OVER DIV
  </div>
  <td>
    <p id="text_field2">
      Prefer this to stay as default text if user moves mouse off the td above
    </p>
  </td>
  <td onmouseover="writeText2('the td works fine')">
      MOUSE OVER TD
  </td>

而事实并非如此:

package main

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

type Scraper struct {
    client http.Client
    timeout int
    tasks chan string
    results chan int
    ntasks int
}

func (s Scraper) Init(timeout int, workers int) {
    s.client = http.Client{
        Timeout: time.Second * time.Duration(timeout),
    }
    s.timeout = timeout
    s.ntasks = 0
    s.Dispatch(workers)
}

func (s Scraper) Wait() {
    for i := 0; i < s.ntasks; i++ {
        <-s.results
    }
}

func (s Scraper) Task(task string) {
    s.tasks <- task // hangs on this line
    s.ntasks++;
}

func (s Scraper) Dispatch(workers int) {
    s.tasks   = make(chan string, 100)
    s.results = make(chan int,    100)
    for i := 0; i < workers; i++ {
        go s.worker(i)
    }
}

func (s Scraper) worker(id int) {
    for task := range <-s.tasks {
        fmt.Println(task)
        s.results <- 0
    }
}

func main() {

    s := Scraper{}
    s.Init(10, 5)
    s.Task("Hello World")
    s.Wait()

}

看着堆栈溢出,我看到未缓冲的通道挂起,但是make(chan string,100)应该创建一个缓冲的通道。

1 个答案:

答案 0 :(得分:0)

将所有接收者更改为指针,如下所示:

func (s *Scraper) Init(timeout int, workers int) // *Scraper not 'Scraper'

有关指针接收器的更多详细信息:https://tour.golang.org/methods/4

@JimB指出-范围也有错误,应该像这样:

func (s *Scraper) worker(id int) {
    // `range s.tasks` not `range <-s.tasks`
    for task := range s.tasks {
        fmt.Println(task)
        s.results <- 0
    }
}

带有接收器和范围修正的游乐场:https://play.golang.org/p/RulKHHfnvJo