go 子线程函数是for循环 为何不生效

问题遇到的现象和发生背景

GO语言初学者,在学习通道和进程时,遇到了点问题

问题相关代码,请勿粘贴截图
package main 

import "fmt"


func main ()  {
    numChan := make (chan  int)
    // 启动主go程
    go func(){
        for i:=0;i<50;i++ {
            numChan <- i
            fmt.Println("这是001",numChan)
            fmt.Println("这是001",i)
        }
    }()
    go func(){
        for i:=0;i<50;i++ {
            data := numChan
            fmt.Println("这是002",data)
        }
    }()
    fmt.Println("这是主进程")
}


运行结果及报错内容

img

我想要达到的结果

两个子进程也正常运行起来,正常输出打印

package main 
import "fmt"
 
func main ()  {
    numChan := make (chan  int)
    // 启动主go程
    go func(){
        for i:=0;i<50;i++ {
            numChan <- i
            fmt.Println("这是001",numChan)
            fmt.Println("这是001",i)
        }
    }()
    go func(){
        for i:=0;i<50;i++ {
            data := numChan
            fmt.Println("这是002",data)
        }
    }()
    <- numChan
    fmt.Println("这是主进程")
}

感谢邀请,试一下看能行不


package main 
 
import "fmt"
 
 
func main ()  {
    fmt.Println("开始主进程")
    numChan := make (chan  int)
    test1(numChan)
    test2(numChan)
    <- numChan
    fmt.Println("结束主进程")
}

func test1(numChan int)
{ 
     for i:=0;i<50;i++ {
            numChan <- i
            fmt.Println("这是001",numChan)
            fmt.Println("这是001",i)
        }
}

func test2(numChan int)
{ 
     for i:=0;i<50;i++ {
            data := numChan
            fmt.Println("这是002",data)
        }
}

 

实际上你开了三个协程,生产者,消费者和主协程,主协程打印了一句话就退出了,导致整个进程退出,只需要阻塞住主协程就可以了,可以用 sync.WaitGroup 或者一个 chan 去做,或者主协程运行一个死循环或 sleep 都可以,再或者直接把消费者任务放在主协程去做.

我不确定你这个程序是要做什么,生产者消费者模型?但看起来是有问题的,上面一个 goroutine 往 chan 中写数据,但没有 chan 去读,且这是一个无缓冲 chan 所以上面的 goroutine 写完一个数据后就会被阻塞住, 或许你想要这种效果?

package main

import (
    "fmt"
    "sync"
)
 
 
func main ()  {
    wg := sync.WaitGroup{}
    numChan := make (chan  int)
    // 启动主go程
    go func(){
        wg.Add(1)
        defer wg.Done()
        for i:=0;i<50;i++ {
            numChan <- i
            fmt.Println("这是001",numChan)
            fmt.Println("这是001",i)
        }
    }()
    go func(){
        wg.Add(1)
        defer wg.Done()
        for i:=0;i<50;i++ {
            data := <- numChan
            fmt.Println("这是002",data)
        }
    }()
    fmt.Println("这是主进程")
    wg.Wait()
}

不管怎样无缓冲 chan 很容易造成 panic,大部分情况有缓冲的会好一些