账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    go语言bufio.NewReader(os.Stdin) 阻塞了goroutine调度,怎么解决?
    • 2019-05-10 00:00
    • 10
    23
    0

    问题描述

    两个goroutine,一个goroutine中做键盘的输入,另一个goroutine做其它数据处理。 运行后,如果我不输入数据,另一个goroutine也停止运行了。也没调度。我希望即使我不输入数据,也不要影响另一个goroutine。

    问题出现的环境背景及自己尝试过哪些方法

    相关代码

    // 请把代码文本粘贴到下方(请勿用图片代替代码)

    package main
    
    import (
        "fmt"
        "os"
        "bufio"
        "math/rand"
    )
    
    func main()  {
        msgChan := make(chan string)
        roundChan := make(chan int)
    
        sleepChan := make(chan bool)
        go input(msgChan)
        go roundNum(roundChan)
    
        go Scheduler(msgChan,roundChan)
    
        <-sleepChan
    }
    
    func Scheduler(msgChan chan string,roundChan chan int)  {
        var(
            msg string
            round int
        )
        for{
            select {
            case msg = <-msgChan:
                 fmt.Println("msg:",msg)
            case round = <- roundChan:
                 fmt.Println(round)
            }
        }
    }
    
    func roundNum(roundChan chan int)  {
        roundChan <- rand.Int()
    }
    
    
    func input(msgChan chan string)  {
        var(
            msg string
            err error
        )
        for{
           fmt.Println("请输入要回复的消息:")
           if msg,err =  bufio.NewReader(os.Stdin).ReadString('\n');err!=nil{
               return
          }
            msgChan<-msg
        }
    
    }

    你期待的结果是什么?实际看到的错误信息又是什么?

    期待: 可以随时输入键盘数据,如果我输入键盘数据两个goroutine都正常运行。如果我不输入键盘数据,也不要影响另一个goroutine的执行。

    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 10 元积分
        全部回答
    • 0
    • 在Go语言中,bufio.NewReader(os.Stdin)默认是阻塞的,因为它在读取标准输入流时会阻塞。如果你想解决这个问题,你可以使用io.Copy和io.LimitReader函数。

      以下是一个示例:

      ```go package main

      import ( "bytes" "fmt" "io" "io/ioutil" "os" "strings" )

      func main() { // 创建一个标准输入流 var in io.Reader // 创建一个缓冲区来保存输入流的原始内容 var buffer bytes.Buffer

      // 使用io.Copy复制输入流的内容到缓冲区
      err := io.Copy(&buffer, &in)
      if err != nil {
          fmt.Println(err)
          return
      }
      
      // 使用io.LimitReader限制读取的最大次数,以便在读取过程中不断更新缓冲区的内容
      max := 1000000
      for {
          // 读取最多1000000个字节
          if buffer.Len() >= max {
              break
          }
      }
      // 将缓冲区的内容写入文件
      err = ioutil.WriteFile("output.txt", buffer.Bytes(), 0644)
      if err != nil {
          fmt.Println(err)
          return
      }
      fmt.Println("文件已创建")
      

      } ```

      在这个示例中,我们首先创建了一个标准输入流,然后使用io.Copy复制输入流的内容到缓冲区。然后,我们使用io.LimitReader限制读取的最大次数,以便在读取过程中不断更新缓冲区的内容。最后,我们将缓冲区的内容写入文件。

      这样,即使在读取过程中,goroutine调度也不会阻塞。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部