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

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

如何關閉等待 I/O 的 goroutine

如何關閉等待 I/O 的 goroutine

Go
桃花長相依 2021-10-11 10:32:31
我創建了兩個 go 例程sender和receiver,sender 將不斷從用戶(鍵盤)獲取數據并寫入流,receiver 將獨立地從流中獲取值將其打印到屏幕上。兩者都使用 goroutine 并發在某個時間點接收器失敗并關閉連接并退出接收器 go 例程,但等待用戶輸入(i/o 操作)的發送器 go 例程不會關閉。這種場景下如何退出所有的goroutine?下面是此場景的示例代碼。package mainimport (    "fmt"    "time")var stop bool = falsefunc sender() {    str := ""    for !stop {        fmt.Scanf("%s", &str)        fmt.Println("Entered :", str)    }       fmt.Println("Closing sender goroutine")}func receiver() {    i := 0    for !stop {        i++        if i > 5 {             stop = true        }        time.Sleep(1 * time.Second)    }       fmt.Println("Closing receiver goroutine")}func main() {    go sender()    go receiver()    /* Wait for goroutines to finish */    for !stop {        time.Sleep(1 * time.Millisecond)    }       time.Sleep(1 * time.Second)    panic("Display stack")}上面的代碼發送者將在 5 個循環接收者退出接收者程序后等待用戶輸入。 I expect when receiver close, go routine which waiting on i/o has to be closed.請幫助我解決這個問題。
查看完整描述

2 回答

?
素胚勾勒不出你

TA貢獻1827條經驗 獲得超9個贊

正如 Dave C 和 JimB 所說,使用通道來協調 goroutine。這是一個可能會有所幫助的示例。


收到用戶的5條消息后退出:


package main


import "fmt"


var pipe = make(chan string) //shares text entered by user

var stop = make(chan bool)   //shares stop signal


func listen() {

    for {

        var input string

        fmt.Scan(&input)

        pipe <- input

    }

}


func write() {

    for i := 0; i < 5; i++ {

        var output string

        output = <-pipe

        fmt.Println("Received", output)

    }


    stop <- true

}


func main() {

    go listen()

    go write()


    <-stop

}


查看完整回答
反對 回復 2021-10-11
?
阿波羅的戰車

TA貢獻1862條經驗 獲得超6個贊

首先,您的代碼有一個圍繞stop變量的競賽。當發生數據競爭時,無法保證您的程序會按照定義的那樣運行。使用通道來同步 goroutine。然而,這不是您繼續編程的原因。


您的代碼在 上阻塞fmt.Scanf,無法檢查stop條件。由于無法中斷 Stdin 上的讀?。òl生在 內部fmt.Scanf),因此您需要在Scanf再次調用之前檢查停止條件。如果沒有更多輸入,但您在 Stdin 上有一個待處理的 Read,處理它的最簡單方法是讓 goroutine 運行。有一些相當復雜的方法可以使用稱為“自管道”的技巧來解決這個問題,但通常不值得付出努力,因為 goroutine 很小并且不占用太多資源。


for !stop {

    fmt.Scanf("%s", &str)

    fmt.Println("Entered :", str)

    // use a channel to detect when to exit

    select {

    case <-stop:

        return

    default:

    }

}


查看完整回答
反對 回復 2021-10-11
  • 2 回答
  • 0 關注
  • 253 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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