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

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

在 Go 中,如何關閉長時間運行的讀取?

在 Go 中,如何關閉長時間運行的讀???

Go
慕容森 2021-08-23 16:44:50
似乎不可能通過通道與執行文件操作的 goroutine 進行雙向通信,除非您阻止文件操作上的通道通信。我怎樣才能解決這強加的限制?表達這個問題的另一種方式......如果我有一個類似于以下在 goroutine 中運行的循環,我如何告訴它關閉連接并退出而不阻塞下一次讀???func readLines(response *http.Response, outgoing chan string) error {    defer response.Body.Close()    reader := bufio.NewReader(response.Body)    for {        line, err := reader.ReadString('\n')        if err != nil {            return err        }        outgoing <- line    }}它不可能從告訴它何時關閉的通道讀取,因為它阻塞了網絡讀取(在我的情況下,這可能需要幾個小時)。簡單地從 goroutine 外部調用 Close() 似乎并不安全,因為 Read/Close 方法似乎不是完全線程安全的。我可以簡單地對在例程內部/外部使用的 response.Body 的引用加鎖,但會導致外部代碼阻塞,直到掛起的讀取完成,我特別希望能夠中斷正在進行的讀取。
查看完整描述

1 回答

?
慕斯709654

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

為了解決這種情況,標準庫中的幾個io.ReadCloser實現支持對Read和Close 的并發調用,其中 Close 中斷了一個活動的 Read。


由 net/http Transport創建的響應正文閱讀器是這些實現之一。在響應主體上同時調用 Read 和 Close 是安全的。


您還可以通過調用Transport CancelRequest 方法來中斷響應正文上的活動讀取。


以下是如何在 body 上使用 close 實現取消:


func readLines(response *http.Response, outgoing chan string, done chan struct{}) error {

    cancel := make(chan struct{})

    go func() {

       select {

       case <-done:

          response.Body.Close()

       case <-cancel:

          return

    }()


    defer response.Body.Close()

    defer close(cancel) // ensure that goroutine exits


    reader := bufio.NewReader(response.Body)

    for {

        line, err := reader.ReadString('\n')

        if err != nil {

            return err

        }

        outgoing <- line

    }

}

從另一個 goroutine 調用 close(done) 將取消對主體的讀取。


查看完整回答
反對 回復 2021-08-23
  • 1 回答
  • 0 關注
  • 260 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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