Difference between the main goroutine and spawned goroutines of a Go program
<p>When creating a server using <code>gRPC</code>, if I start the <code>gRPC</code> server in the main process, it can deal with as many as requests (thousands) from clients. However, if I start the server as a goroutine, it can only handle some requests (hundreds) and after get stuck. I have tested and confirmed this with a very simple example, google.golang.org/grpc/examples/helloworld.</p>

<p>Is it because spawned goroutines stack size is very small (2Kbytes), and the main goroutine's much larger? What's the difference between the main goroutine and spawned goroutines?</p>

<p>Example <a href="https://github.com/grpc/grpc-go/tree/master/examples/helloworld" rel="nofollow">link</a>. Modified parts of the example as follows.</p>

<p><strong>greeter_server/main.go</strong></p>

<pre><code>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, &amp;server{})
        s.Serve(lis)
    }() 

    for {
    }   
}
</code></pre>

<p><strong>greeter_client/main.go</strong></p>

<pre><code>func main() {
    // Set up a connection to the server.
    for i := 0; i &lt; 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 &lt; 500; i++ {
            // Contact the server and print out its response.
            name := defaultName
            if len(os.Args) &gt; 1 {
                name = os.Args[1]
            }
            r, err := c.SayHello(context.Background(), &amp;pb.HelloRequest{Name: name})
            if err != nil {
                log.Fatalf("could not greet: %v", err)
            }
            log.Printf("%d's Greeting: %s", i, r.Message)
        }
    }
}
</code></pre>