iT邦幫忙

0

Golang 如何同時在多個不同console輸出?

  • 分享至 

  • xImage

我正在練習使用goroutine,發現兩個goroutine都用fmt輸出的話畫面會變得很難閱讀

func main() {
	s1 := rand.NewSource(time.Now().UnixNano())
	r1 := rand.New(s1)
	wg := &sync.WaitGroup{}
	t1 := func(wg *sync.WaitGroup) {
		for i := 0; i < 100; i++ {
			time.Sleep(time.Microsecond * time.Duration(r1.Intn(100)))
			fmt.Println("T1 : ", i)
		}
		wg.Done()
	}
	t2 := func(wg *sync.WaitGroup) {
		for i := 0; i < 100; i++ {
			time.Sleep(time.Microsecond * time.Duration(r1.Intn(100)))
			fmt.Println("T2 : ", i)
		}
		wg.Done()
	}
	wg.Add(2)
	go t1(wg)
	go t2(wg)
	wg.Wait()
}

輸出:

T1 :  0
T2 :  0
T2 :  1
T1 :  1
T1 :  2
T2 :  2
T1 :  3
T2 :  3
T1 :  4
T2 :  4
T1 :  5
T2 :  5
T1 :  6
T2 :  6
T2 :  7
T1 :  7
T2 :  8
T1 :  8
T1 :  9
T2 :  9
T2 :  10
T1 :  10
......

有沒有什麼方法可以打開兩個console來分別顯示兩個goroutine的輸出?

更新:
我找到解法了
首先啟動我的程式,並掛載一個TCP Server


func main() {
	fmt.Println("Now Run 2 client terminals...")
	ln, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		log.Fatal(err)
	}
	w1, err := ln.Accept()
	if err != nil {
		log.Fatal(err)
	}
	defer w1.Close()
	fmt.Println("Terminal 1 connected.")
	w2, err := ln.Accept()
	if err != nil {
		log.Fatal(err)
	}
	defer w2.Close()
	fmt.Println("Terminal 2 connected.")

	// your code:
	s1 := rand.NewSource(time.Now().UnixNano())
	r1 := rand.New(s1)
	wg := &sync.WaitGroup{}
	t1 := func(wg *sync.WaitGroup) {
		for i := 0; i < 100; i++ {
			time.Sleep(time.Microsecond * time.Duration(r1.Intn(100)))
			fmt.Fprintln(w1, "T1 : ", i)
		}
		wg.Done()
	}
	t2 := func(wg *sync.WaitGroup) {
		for i := 0; i < 100; i++ {
			time.Sleep(time.Microsecond * time.Duration(r1.Intn(100)))
			fmt.Fprintln(w2, "T2 : ", i)
		}
		wg.Done()
	}
	wg.Add(2)
	go t1(wg)
	go t2(wg)
	wg.Wait()
}

然後顯示的時候,開兩個終端,執行兩次這個

func main() {
    tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8080")
    if err != nil {
        log.Fatal(err)
    }
    con, err := net.DialTCP("tcp", nil, tcpAddr)
    if err != nil {
        log.Fatal(err)
    }
    defer con.Close()

    buf := make([]byte, 1024)
    for {
        n, err := con.Read(buf)
        if err != nil {
            break
        }
        fmt.Print(string(buf[:n]))
    }
}
froce iT邦大師 1 級 ‧ 2021-05-12 16:23:31 檢舉
你會寫這種顯示的code也只有在練習的時候,這種效果也只是告訴你goroutine他不是阻塞的而已,不用想太多。
這種亂七八糟的顯示結果反而是教學者要你看的。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答