当前位置: 首页 > 知识库问答 >
问题:

通道仅接受一次值-golang

鱼阳伯
2023-03-14

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

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

然后,main函数为“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())
    }
  }
}

编辑:正如Damsham指出的,线程在接受值一次后退出。用他建议修复代码的代码替换线程创建循环

共有1个答案

司寇山
2023-03-14

因为一旦searchAndLog接收到频道上的内容,它就会执行其操作并退出。因此,在5个目录之后,所有运行searchAndLoggoroutine现在都消失了。试试这个:

// Create 5 threads of searchAndLog()
for i := 0; i < numThreads; i++ {
  go func(i int) {
     for {
        searchAndLog(dir[i], i)
     }
  }(i)
}
 类似资料:
  • 问题内容: 我在表中有一列称为“患者类型”。我想确保只能将2个值插入opd或accepted列中,除此之外,所有其他输入均无效。 以下是我想要的示例 如何确保该列仅接受“ opd”或“ admitted”作为“患者类型”列的数据。 问题答案: 您需要检查约束。 从现在开始,您需要检查它是否在MySQL中特别有效。 似乎不起作用(或者至少几年前没有)。 MySQL CHECK约束 MySQL CHE

  • 问题内容: 我需要确保某个字段仅将数字作为值。输入的内容不是表单的一部分。因此它不会被提交,因此在提交期间进行验证不是一种选择。我希望用户无法输入数字以外的任何字符。 有没有一种巧妙的方法可以实现这一目标? 问题答案: HTML 5 您可以使用HTML5输入类型数字来限制仅数字输入: 这仅在HTML5投诉浏览器中有效。确保您的html文档的doctype为: 的JavaScript 更新: 为此,

  • 我在运行使用Netty的服务时遇到了问题。它启动和工作正常,但只有一次。在此之后,不接受任何连接(它们将立即被删除)。 当我第一次使用(示例端口,随便什么)连接到服务器时,一切正常: 客户端会话: 服务器日志: --编辑2-- 只要连接处于活动状态,服务器就可以正常工作--在关闭连接之前,我可以轻松地交换请求/响应。 不要被IP地址迷惑,这是一个转发到Docker的本地端口,应用程序就是在那里启动

  • 问题内容: 我正在编写一个应用程序,并试图将简单的AJAX功能绑定在一起。它在Mozilla Firefox中运行良好,但是Internet Explorer中有一个有趣的错误:每个链接只能单击一次。浏览器必须完全重新启动,只是重新加载页面将无法进行。我编写了一个非常简单的示例应用程序来演示这一点。 Javascript转载如下: 任何帮助,将不胜感激。 问题答案: 发生这种情况是因为Intern

  • 问题 你希望你的脚本接受任何用户认为最简单的输入方式。包括将命令行的输出通过管道传递给该脚本、 重定向文件到该脚本,或在命令行中传递一个文件名或文件名列表给该脚本。 解决方案 Python内置的 fileinput 模块让这个变得简单。如果你有一个下面这样的脚本: #!/usr/bin/env python3 import fileinput with fileinput.input() as

  • 问题内容: 我希望用户仅输入字母或空格(如果用户输入其他字符),我想给jOptionPane消息,我已经搜索过,并且尝试了以下代码 但是现在无论我输入什么都会给出错误 现在我更改了代码 现在它仅在用户输入数字时发出消息。我该如何解决 问题答案: 使用一个,这是我制作的一个示例,它将仅接受字母字符和空格: