Comment

Comment by neonsunset

What this likely means is for you to take advantage of the underlying runtime multiplexing green threads over multiple physical ones running on multiple cores, you need to explicitly fork the execution flow.

This could be as simple as a web server firing off a new green thread or a goroutine for an incoming request, or as contrived as doing so manually within a function scope.

In practice, there really is not much difference with async/await. "Green threads" is a combination of implementation details and a subset of what async/await abstractions achieve.

Effectively, Goroutines are in many ways similar to C# Task<T>s. The difference is that in Go you are expected to explicitly send the result via a channel or some other data structure and then synchronize the completion of the execution, where-as with tasks you simply await that.

There could be an argument made about preference of implicit suspend (Go, Java, BEAM family) over explicit suspend (C#/F#, Rust, JS, Python, C++ co_await, Swift), but for practical purposes invoking a function with 'go' keyword in Golang is very similar to firing off a synchronous method with Task.Run in C#, or calling an asynchronous method (with sufficiently short body before first yield) and not immediately awaiting it.

As I usually post it on HN, tasks make the following patterns trivial:

    using var http = new HttpClient {
        BaseAddress = new("https://news.ycombinator.com/")
    };

    // not immediately awaited requests are executed in parallel
    var frontPage = http.GetStringAsync("news?p=1");
    var secondPage = http.GetStringAsync("news?p=2");

    Console.WriteLine($"{await frontPage}\n\n{await secondPage}");
parent neonsunset 2 years ago

Discussion

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton