Diferencia entre la goroutina principal y las goroutines generadas de un programa Go

Al crear un servidor usandogRPC, si empiezo elgRPC servidor en el proceso principal, puede manejar tantas solicitudes (miles) de clientes. Sin embargo, si inicio el servidor como una rutina, solo puede manejar algunas solicitudes (cientos) y luego quedar atascado. He probado y confirmado esto con un ejemplo muy simple, google.golang.org/grpc/examples/helloworld.

¿Es porque el tamaño de la pila de gorutinas generadas es muy pequeño (2Kbytes) y la gorutina principal es mucho más grande? ¿Cuál es la diferencia entre la goroutina principal y las goroutines generadas?

Ejemploenlazar. Partes modificadas del ejemplo de la siguiente manera.

greeter_server / main.go

func main() {
    go func() {
        lis, err := net.Listen("tcp", port)
        if err != nil {
            log.Fatalf("failed to listen: %v", err)
        }   
        s := grpc.NewServer()
        pb.RegisterGreeterServer(s, &server{})
        s.Serve(lis)
    }() 

    for {
    }   
}

greeter_client / main.go

func main() {
    // Set up a connection to the server.
    for i := 0; i < 500; i++ {
        conn, err := grpc.Dial(address, grpc.WithInsecure())
        if err != nil {
            log.Fatalf("did not connect: %v", err)
        }
        defer conn.Close()
        c := pb.NewGreeterClient(conn)

        for i := 0; i < 500; i++ {
            // Contact the server and print out its response.
            name := defaultName
            if len(os.Args) > 1 {
                name = os.Args[1]
            }
            r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})
            if err != nil {
                log.Fatalf("could not greet: %v", err)
            }
            log.Printf("%d's Greeting: %s", i, r.Message)
        }
    }
}

Respuestas a la pregunta(1)

Su respuesta a la pregunta