亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用多個掃描儀時,scanner.Scan() 的順序問題

使用多個掃描儀時,scanner.Scan() 的順序問題

Go
Helenr 2022-06-01 16:22:36
對于某些背景,我對 Go 很陌生,但是在工作中編寫這個程序的人離開了,所以現在代碼是我的責任。該程序包裝了一個 CLI 工具,用于寫入 stdout 和 stderr。我們希望在處理輸出的同時優雅地處理底層工具的錯誤。這是當前正在使用的相關代碼片段:cmd := exec.Command(args[0], args[1:]...)stdout, err := cmd.StdoutPipe()if err != nil {        log.Fatal(err)}stderr, err := cmd.StderrPipe()if err != nil {        log.Fatal(err)}cmd.Start()scanner := bufio.NewScanner(stdout)errScanner := bufio.NewScanner(stderr)for errScanner.Scan() {        err := errScanner.Text()        log.Fatal(err)}for scanner.Scan() {        // proccess stdout data}if scanner.Err() != nil {        log.Fatal(scanner.Err())}cmd.Wait()通常這工作正常。但是,如果寫入標準輸出的數據大小超過 buf.MaxScanTokenSize (即 64 KB),則程序會掛起而沒有錯誤。底層命令完成,但沒有命中任何循環掃描器。我發現如果我交換 errScanner.Scan() 和scanner.Scan() 的位置,那么問題就不再發生了。這就是我的意思:cmd := exec.Command(args[0], args[1:]...)stdout, err := cmd.StdoutPipe()if err != nil {        log.Fatal(err)}stderr, err := cmd.StderrPipe()if err != nil {        log.Fatal(err)}cmd.Start()scanner := bufio.NewScanner(stdout)errScanner := bufio.NewScanner(stderr)for scanner.Scan() {        // proccess stdout}for errScanner.Scan() {        err := errScanner.Text()        log.Fatal(err)}if scanner.Err() != nil {        log.Fatal(scanner.Err())}cmd.Wait()有誰知道為什么會發生最初的問題以及為什么交換兩個掃描儀可以解決問題?我的猜測是兩個掃描儀共享相同的底層緩沖區,這可能會導致一些問題,但我創建了兩個不同的緩沖區并將它們分配給掃描儀,但并沒有解決問題。任何幫助表示贊賞!
查看完整描述

1 回答

?
心有法竹

TA貢獻1866條經驗 獲得超5個贊

它的編寫方式是,您的程序將等待直到從其中一個流中讀取所有數據,具體取決于順序。如果在從該流讀取時,第二個流緩沖區已填滿,則正在運行的程序(您正在讀取其輸出的程序)將阻塞,因為它無法再向該流寫入任何輸出。


看起來您并沒有真正處理錯誤,因此您可以在 goroutine 中讀取錯誤流:


go () {

  for errScanner.Scan() {

     ...

  }

}()


for scanner.Scan() {

  ...

}


查看完整回答
反對 回復 2022-06-01
  • 1 回答
  • 0 關注
  • 121 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號