demo1:

    1. const (
    2. THREAD_NUM int = 5
    3. THREAD_PRINT int = 0
    4. THREAD_NEXT_STOPPED int = 1
    5. THREAD_THIS_STOPPED int = 2
    6. )
    7. type Thread_pipline_printer struct {
    8. idx int
    9. status int
    10. next_chan chan int
    11. }
    12. func (printer *Thread_pipline_printer) Print(max_num int, pre Thread_pipline_printer, wg *sync.WaitGroup) {
    13. defer wg.Done()
    14. for {
    15. print_num := <-pre.next_chan
    16. if print_num < max_num {
    17. print_format(printer.idx, print_num)
    18. }
    19. if printer.status == THREAD_PRINT {
    20. printer.next_chan <- (print_num + 1)
    21. }
    22. if print_num > max_num {
    23. printer.status = THREAD_THIS_STOPPED
    24. return
    25. } else if print_num == max_num {//注意。。。。。。。。。。。
    26. printer.status = THREAD_NEXT_STOPPED
    27. }
    28. }
    29. }
    30. func print_format(thread_idx int, print_num int) {
    31. fmt.Printf("Printer%d-%d\n", thread_idx, print_num)
    32. }
    33. func Print() {
    34. printers := make([]Thread_pipline_printer, THREAD_NUM)
    35. for i := 0; i < THREAD_NUM; i++ {
    36. printers[i] =
    37. Thread_pipline_printer{i, THREAD_PRINT, make(chan int)}
    38. }
    39. start := 1
    40. end := 100
    41. wg := &sync.WaitGroup{}
    42. wg.Add(THREAD_NUM)
    43. for i := 0; i < THREAD_NUM; i++ {
    44. input_num := (i + THREAD_NUM - 1) % THREAD_NUM
    45. go printers[i].Print(end+1, printers[input_num], wg)
    46. }
    47. printers[THREAD_NUM-1].next_chan <- start
    48. wg.Wait()
    49. }

    这段代码用Chanel将五个协程连接起来,最后注意打印完最后一个数字的协程不能立即关闭,需要将chanel传递一遍依次关闭。否则会造成死锁。

    demo2:

    1. func printer(i int, inCh chan int, outCh chan int, endNum int, wg *sync.WaitGroup) {
    2. for {
    3. n, ok := <-inCh
    4. if !ok {
    5. return
    6. }
    7. fmt.Printf("Printer-%d %d\n", i+1, n)
    8. if n == endNum {
    9. wg.Done()
    10. return
    11. }
    12. outCh <- n + 1
    13. }
    14. }
    15. func main() {
    16. const n = 5
    17. const endNum = 100
    18. chs := make([]chan int, n)
    19. for i := 0; i < n; i++ {
    20. chs[i] = make(chan int)
    21. }
    22. wg := &sync.WaitGroup{}
    23. wg.Add(1)
    24. for i := 0; i < n; i++ {
    25. inCh := chs[i]
    26. outCh := chs[(i+1)%n]
    27. go printer(i, inCh, outCh, endNum, wg)
    28. }
    29. chs[0] <- 1
    30. wg.Wait()
    31. for i := 0; i < n; i++ {
    32. close(chs[i])
    33. }
    34. }

    这段代码和上边道理是一样的,都是用channel将前后协程连接。这段代码按理说最后是会死锁的(跟第一段代码的注意事项是一个道理)。但是他waitgroup设置的是1,那就是说当有一个协程done了(打印最后一个数字的协程),主协程就不再等待,运行下去结束后其他协程自然会结束。其实第一段代码也可以将waitgroup设置成1,在30行下边加个return,也能跟这段代码一样强制结束。不过这种方式可能不够优雅。