当前位置: 首页 > 面试题库 >

Golang Goroutine不在通道内部运行

程举
2023-03-14
问题内容

我正在尝试实现字数统计程序,但是第一步我遇到了一些问题。

这是我的代码

package main

import (
    "fmt"
    "os"
    "bufio"
    "sync"
)

// Load data into channel
func laodData(arr []string,channel chan string,wg sync.WaitGroup) {
    for _,path := range arr {
        file,err := os.Open(path)
        fmt.Println("begin to laodData ", path)
        if err != nil {
            fmt.Println(err)
            os.Exit(-1)
        }
        defer file.Close()
        reader := bufio.NewReaderSize(file, 32*10*1024)
        i := 0
        for {
            line,err := reader.ReadString('\n')
            channel <- line
            if err != nil {
                break
            }
            i++
            if i%200 == 0 {
                fmt.Println(i," lines parsed")
            }
        }
        fmt.Println("finish laodData ", path)
    }
    wg.Done()
}

// dispatch data lines into different mappers
func dispatcher(channel chan string,wg sync.WaitGroup){
    fmt.Println("pull data 11")
    line,ok := <- channel
    fmt.Println(ok)
    for ok {
        fmt.Println(line)
        line,ok = <- channel
    }
    fmt.Println("pull data 22")
    wg.Done()
}

func main() {
    path := os.Args
    if len(path) < 2 {
        fmt.Println("Need Input Files")
        os.Exit(0)
    }
    var wg sync.WaitGroup
    wg.Add(2)

    channel := make(chan string)
    defer close(channel)

    fmt.Println("before dispatcher")
    go laodData(path[1:],channel,wg)
    go dispatcher(channel,wg)
    wg.Wait()

    fmt.Println("after dispatcher")
}

这是我的输出:

...

finish laodData  result.txt

throw: all goroutines are asleep - deadlock!

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0x42154100, 0x42154100)
    /usr/local/go/src/pkg/runtime/zsema_amd64.c:146 +0x25
sync.(*WaitGroup).Wait(0x4213b440, 0x0)
    /usr/local/go/src/pkg/sync/waitgroup.go:79 +0xf2
main.main()
    /Users/kuankuan/go/src/mreasy/main.go:66 +0x238

goroutine 2 [syscall]:
created by runtime.main
    /usr/local/go/src/pkg/runtime/proc.c:221

goroutine 4 [chan receive]:
main.dispatcher(0x42115a50, 0x0, 0x2, 0x0)
    /Users/kuankuan/go/src/mreasy/main.go:45 +0x223
created by main.main
    /Users/kuankuan/go/src/mreasy/main.go:65 +0x228
exit status 2

谢谢 !


问题答案:

当主goroutine退出时,程序终止,因此dispatcher()没有时间做任何事情。您需要封锁main()直到dispatcher()完成。通道可用于此目的:

package main

import (
    "fmt"
    "os"
    "bufio"
)

var done = make(chan bool)             // create channel

// Load files and send them into a channel for mappers reading.
func dispatcher(arr []string,channel chan string) {
    for _,path := range arr {
        file,err := os.Open(path)
        fmt.Println("begin to dispatch ", path)
        if err != nil {
            fmt.Println(err)
            os.Exit(-1)
        }
        defer file.Close()
        reader := bufio.NewReaderSize(file, 32*10*1024)
        i := 0
        for {
            line,_ := reader.ReadString('\n')
            channel <- line
            i++
            if i%200 == 0 {
                fmt.Println(i," lines parsed")
            }
        }
        fmt.Println("finish dispatch ", path)
    }
    done <- true                 // notify main() of completion
}

func main() {
    path := os.Args
    if len(path) < 2 {
        fmt.Println("Need Input Files")
        os.Exit(0)
    }
    channel := make(chan string)
    fmt.Println("before dispatcher")
    go dispatcher(path[1:],channel)
    <-done                 // wait for dispatcher()
    fmt.Println("after dispatcher")
}


 类似资料:
  • 我开始开发一个spring cloud stream项目。我已通过@Streamlistener注释成功接收到来自Kafka的消息。在将消息发送到任何输出通道之前,我必须通过调用externalservice或DB调用来转换有效负载。我不想从同一个streamlistener方法调用外部服务或DB方法。我的问题是,我们能否在Spring云流中创建内部通道(如Spring集成DSL流)?

  • 如何在docker容器中运行基于的测试用例? 我有一个简单的Spring Boot应用程序,它具有集成测试(组件级),使用与容器交互。测试用例正在破坏来自外部容器(本地机器)的罚款。 我们正在容器中运行所有内容,并且build正在docker jenkins映像上运行。Docker文件正在创建jar,然后创建image。找不到安装的docker。下面是我的docker文件。 处理这个案子最好的办法

  • YouTube频道可以有几个“相关”频道的列表。例如,音乐频道有相关的流派频道:嘻哈、流行、摇滚、乡村等。 音乐频道:http://www.youtube.com/channel/UC-9-kyTW8ZkZNDHQJ6FgpwQ 音乐频道相关频道:http://www . YouTube . com/Channel/UC-9-kytw 8 zkzndhqj 6 fg pwq/Channels 我可

  • 问题内容: 我正在尝试在作为Jenkins Pipeline一部分运行的docker容器内执行一些git查询。在docker容器外面,sshsgent工作正常,我可以访问我的SCM没问题。在容器内部,我收到主机密钥验证问题。 有人可以帮助我解决我所犯的错误吗? 首先whoami呼叫输出: docker容器输出中的第二个调用(和回显): 问题答案: 主机密钥验证失败 容器中的SSH连接无法验证主机(

  • 问题内容: 我在Ubuntu 13.04上的码头上运行servlet时遇到问题。使用安装服务器,并开始使用。该应用程序需要该类,但出现类未找到错误。这是堆栈跟踪: 到目前为止,我有: 1)检查了用于启动码头的命令以使用ps查找类路径: 2)检查应包含缺少类的jar: 有人可以建议我下一步该怎么做吗?谢谢。 问题答案: 将放入您的webapp的 从stacktrace中可以看到,您正在尝试从Web应

  • 问题内容: 在pub- sub的情况下,Redis使用什么机制将消息保留在内存中?如果没有客户端订阅,消息将如何处理?Redis会缓冲它们吗?有没有一种配置最小值的方法。和最大 每个通道分配的内存? 问题答案: 在实现(x)中可以看到,Redis不会在Pub / Sub上下文中将消息保留在内存中: 邮件会发送给监听该频道的客户端(如果有), 该消息将发送给正在侦听匹配频道(如果有)的客户端。 然后