How to make goroutines output in multiple different consoles?

Issue

I am practicing using goroutines and found that if both goroutines are printing at the same time, it becomes difficult to read.

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()
}

Output:

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
......

Is there any way to open multiple consoles and let two goroutines output in different consoles?

Solution

  1. You may use a simple TCP terminal server– first run this TCP terminal server and you don’t need to close it as long as you need ( or just use Netcat Command: nc -l 8080 then goto #2 and write to this TCP connection e.g. "127.0.0.1:8080"):
package main

import (
    "io"
    "log"
    "net"
    "os"
)

func main() {
    ln, err := net.Listen("tcp", "127.0.0.1:8080")
    if err != nil {
        log.Fatal(err)
    }
    for {
        w1, err := ln.Accept()
        if err != nil {
            log.Fatal(err)
        }
        io.Copy(os.Stdout, w1)
        w1.Close()
    }
}
  1. Then add this to your code:
    w1, err := net.Dial("tcp", "127.0.0.1:8080")
    if err != nil {
        log.Fatal(err)
    }
    defer w1.Close()
  1. Then use w1 as your another io.Writer in your code e.g. fmt.Fprintln(w1, "T1 : ", i), an example:
package main

import (
    "fmt"
    "log"
    "math/rand"
    "net"
    "sync"
    "time"
)

func main() {
    w1, err := net.Dial("tcp", "127.0.0.1:8080")
    if err != nil {
        log.Fatal(err)
    }
    defer w1.Close()

    // 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.Println("T2 : ", i)
        }
        wg.Done()
    }
    wg.Add(2)
    go t1(wg)
    go t2(wg)
    wg.Wait()
}

Answered By – wasmup

Answer Checked By – Robin (GoLangFix Admin)

Leave a Reply

Your email address will not be published.