• package main
    
    import (
        "fmt"
        "math/rand"
        "runtime"
        "sort"
    )
    
    const GO_SUM = 10
    
    type message struct {
        num int
        createNum int
        isLast bool
    }
    
    func main() {
        countCh     := make(chan struct{}, GO_SUM)
        sendCh      := make([]chan *message, GO_SUM)
        receiveCh   := make([]chan *message, GO_SUM)
        overCh      := make([]chan struct{}, GO_SUM)
        for i := 0; i < GO_SUM; i++ {
            sendCh[i] = make(chan *message, 1)
            receiveCh[i] = make(chan *message, 1)
            overCh[i] = make(chan struct{}, 1)
            go outPut(i, sendCh[i], receiveCh[i], countCh, overCh[i])
        }
    
        for {
            if len(countCh) == GO_SUM {
                data := make([]*message, GO_SUM)
                for i := 0; i < GO_SUM; i++{
                    select {
                    case tmp := <-sendCh[i]:
                        data[i] = tmp
                    }
                }
                sort.Slice(data, func(i, j int) bool {
                    return data[i].createNum < data[j].createNum
                })
                data[GO_SUM - 1].isLast = true
                for i := 0; i < GO_SUM; i++{
                    tmp := data[i]
                    receiveCh[tmp.num] <- tmp
                    <-overCh[tmp.num]
                }
                for i := 0; i < GO_SUM; i++ {
                    <-countCh
                }
            }
            runtime.Gosched()
        }
    }
    
    func outPut(num int, send chan *message, receive chan *message, countCh, overCh chan struct{}) {
        for {
            tmp := &message{
                num,
                rand.Intn(100) + 1,
                false,
            }
            send <- tmp
            countCh <- struct{}{}
            result := <-receive
            fmt.Print(result.createNum, " ")
            if result.isLast {
                fmt.Println()
            }
            overCh <- struct{}{}
            runtime.Gosched()
        }
    }