2

I had created a test program to check my understanding of how Golang handles Network IO. The below program creates 1000 goroutines and in each goroutine, it will make a Network IO request.

When I tried to monitor the number of threads getting used, it goes up to 400 Threads. I had used the top command to monitor, My understanding is for network io Golang uses netpoll(i.e async io).

Please correct me if my understanding is wrong.

OS: macos high sierra

Go version: go1.11.2 darwin/amd64

package main

import (
    "encoding/json"
    "log"
    "net/http"
    "sync"
    "time"
)

func main() {
    timeout := time.Duration(5 * time.Second)
    client := http.Client{
        Timeout: timeout,
    }
    var wg sync.WaitGroup

    start := time.Now()
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go callAPI(&wg, client)
    }
    wg.Wait()
    log.Println(time.Since(start))
}

func callAPI(wg *sync.WaitGroup, client http.Client) {
    defer wg.Done()
    url := `JSON-API-URL-OF-YOUR-CHOICE` // Please enter a valid json api url.
    request, err := http.NewRequest("GET", url, nil)
    if err != nil {
        log.Fatalln(err)
    }

    resp, err := client.Do(request)
    if err != nil {
        log.Fatalln(err)
    }

    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    defer resp.Body.Close()

    log.Println(result)
}
1
  • When you say: "When I tried to monitor the number of threads getting used, it goes up to 400 Threads"..... Do you mean 400 Goroutines or 400 OS threads? Commented Mar 22, 2024 at 1:11

1 Answer 1

4

When a thread is blocked on a system IO call, Go may create a new thread to allow other goroutines to continue to run. This has a good explanation: https://povilasv.me/go-scheduler/:

Interesting things happen when your goroutine makes a blocking syscall. Blocking syscall will be intercepted, if there are Gs to run, runtime will detach the thread from the P and create a new OS thread (if idle thread doesn’t exist) to service that processor.

So, instead of having a handful of threads and utilizing 0% of your CPU because all the threads are tied up waiting on a blocking syscall to return, instead it sets those threads aside and spins up new threads so non-blocked goroutines can do their work while it waits for the blocking syscall(s) to return.

Sign up to request clarification or add additional context in comments.

2 Comments

If the number of blocking calls is increased there is a chance of the application crash due to lack of system resources right? how to avoid such situations.
If you use too much memory there is a chance the app will crash due to being unable to allocate requested memory. To avoid that, use less memory or run on a system with more memory.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.