通道仅接受一次值-golang

通道仅接受一次值-golang,go,channel,Go,Channel,我刚从围棋开始。下面是我试图通过以下代码实现的内容 Main函数为searchAndLog()创建5个线程。此函数接受一个通道,通过该通道它将接收到一个目录的路径,它将搜索一个名为“.DS_Store”的文件,然后对其执行操作 然后,主函数为“file path.Walk()”创建另一个线程。该线程将遍历传递给它的目录,对于它遇到的每个目录(在walkFunc()中),它将执行select语句,将目录路径传递给5个线程中的一个 但是当我运行这个程序时,“filepath.Walk()”遇到的前五

我刚从围棋开始。下面是我试图通过以下代码实现的内容

Main函数为searchAndLog()创建5个线程。此函数接受一个通道,通过该通道它将接收到一个目录的路径,它将搜索一个名为“.DS_Store”的文件,然后对其执行操作

然后,主函数为“file path.Walk()”
创建另一个线程。该线程将遍历传递给它的目录,对于它遇到的每个目录(在walkFunc()中),它将执行select语句,将目录路径传递给5个线程中的一个

但是当我运行这个程序时,“filepath.Walk()”遇到的前五个目录将它传递给五个线程,但是一旦它将一个目录传递给每个线程一次,它就会停止。select中的频道dir[0]dir[5]不会再次接受值

我做错了什么

package main

// A simple multithreaded program to calculate how many
// and total disk space occupyed by all ".DS_Store" files.
// It also logs the location of each file along with its
// size

import (
  "fmt"
  "io/ioutil"
  "os"
  "flag"
  "path/filepath"
)

// Returns true if path is a directory otherwise false
func isDirectory(path string) bool {
  file, err := os.Open(path)
  if err != nil {
    fmt.Println(err)
    return false
  }
  defer file.Close()
  fi, err := file.Stat()
  if err != nil {
    fmt.Println(err)
    return false
  }
  return (fi.Mode()).IsDir()
}

func main() {

  // Command line flag to pass in how many threads to swapn
  var numThreads int
  flag.IntVar(&numThreads, "t", 5, "number of threads")
  flag.Parse()
  fmt.Println("numThreads: ", numThreads)

  // 5 Channels for 5 threads
  var dir [5]chan string
  for i, _ := range dir {
    dir[i] = make(chan string)
  }

  // This is the function that will be passed to filepath.Walk()
  // "select" will be executed only if path points to directory
  walkFunc := func(path string, info os.FileInfo, err error) error {
    fmt.Println("Visited: ", path)
    if isDirectory(path) {
      select {
        case dir[0] <- path:
          fmt.Println("Thread: 1")
        case dir[1] <- path:
          fmt.Println("Thread: 2")
        case dir[2] <- path:
          fmt.Println("Thread: 3")
        case dir[3] <- path:
          fmt.Println("Thread: 4")
        case dir[4] <- path:
          fmt.Println("Thread: 5")
        }
    }
    return nil
  }

  // Create 5 threads of searchAndLog()
  for i := 0; i < numThreads; i++ {
    go searchAndLog(dir[i], i)
  }

  go filepath.Walk("/Users/nikhil/Workspace", walkFunc)

  var input string
  fmt.Scanln(&input)
}

// id is passed to identify the thread in the println statements
func searchAndLog(dirpath chan string, id int) {
  directory := <- dirpath
  fmt.Println("Thread # ", id + 1, directory)
  files, _ := ioutil.ReadDir(directory)
  for _, f := range files {
    if f.Name() == ".DS_Store" {
      fmt.Println("Thread # ", id + 1, f.Size())
    }
  }
}
主程序包
//一个简单的多线程程序,用来计算
//以及所有“.DS_Store”文件占用的总磁盘空间。
//它还记录每个文件的位置以及文件名
//大小
进口(
“fmt”
“io/ioutil”
“操作系统”
“旗帜”
“路径/文件路径”
)
//如果路径是目录,则返回true,否则返回false
func isDirectory(路径字符串)bool{
文件,错误:=os.Open(路径)
如果错误!=零{
fmt.Println(错误)
返回错误
}
延迟文件。关闭()
fi,err:=file.Stat()
如果错误!=零{
fmt.Println(错误)
返回错误
}
返回(fi.Mode()).IsDir()
}
func main(){
//传递要交换多少线程的命令行标志
var numThreads int
flag.IntVar(&numThreads,“t”,5,“线程数”)
flag.Parse()
Println(“numThreads:,numThreads”)
//5个通道用于5个线程
var dir[5]chan字符串
对于i,u:=range dir{
dir[i]=make(chan字符串)
}
//这是将传递给filepath.Walk()的函数
//仅当路径指向目录时,才会执行“选择”
walkFunc:=func(路径字符串,info os.FileInfo,err error)错误{
fmt.Println(“已访问:”,路径)
if isDirectory(路径){
挑选{

case dir[0]因为一旦
searchAndLog
接收到频道上的内容,它将执行其操作并退出。因此,在5个目录之后,所有运行
searchAndLog
的goroutines现在都消失了。请尝试以下操作:

// Create 5 threads of searchAndLog()
for i := 0; i < numThreads; i++ {
  go func(i int) {
     for {
        searchAndLog(dir[i], i)
     }
  }(i)
}
//创建searchAndLog()的5个线程
对于i:=0;i