iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🤔

Abstraction of Concurrency in Go

に公開

I came across an interesting article.

https://zenn.dev/it/articles/e975f08392ea846d9d7b

It provides a clear introduction to the differences between various programming languages, and I found the recent trends in parallel processing in Rust particularly informative as I wasn't familiar with them. However, I felt that Go required a bit more explanation, so I'm writing this supplementary article.

"Concurrency" and "Parallelism" in Go

I was originally going to write about the difference between "concurrency" and "parallelism," but it turns out it has already been thoroughly covered in this excellent article orz

https://zenn.dev/koron/articles/3ddcaaeae37f9befdf70

...Pulling myself back together, there is a book that can be considered the bible for "concurrency" in Go.

https://www.amazon.co.jp/dp/4873118468

In this book, the difference between "concurrency" and "parallelism" is described as follows (Chapter 2.1):

Concurrency is a property of the code; parallelism is a property of the running program.

Why can this be stated so definitively? It can likely be summarized by this sentence:

Concurrency and parallelism are separate for a reason: it turns out that this is a very powerful abstraction when designing your code, and Go makes the most of it.

Goroutine as a Coroutine

The keyword that comes to mind regarding abstracted concurrency is coroutine. Goroutines can be considered a type of coroutine. By the way, if you look up coroutine on Wikipedia, it says:

Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing execution to be suspended and resumed. Coroutines are well-suited for implementing familiar program components such as cooperative tasks, exceptions, event loops, iterators, infinite lists and pipes.

While it is stated here that coroutines are non-preemptive, goroutines in Go have acquired preemptive asynchronous processing since 1.14 (except for some platforms).

Goroutines are now asynchronously preemptible. As a result, loops without function calls no longer potentially deadlock the scheduler or significantly delay garbage collection. This is supported on all platforms except windows/arm, darwin/arm, js/wasm, and plan9/*.

As a result, programmers can focus on coding "concurrency" without having to worry about the implementation details of "parallelism."

Concurrency Trade-offs

Personally, I like both Go and [Rust][1], so I often think about the comparison between the two. However, seeing the "How to leverage multi-core from a multi-language perspective" article I introduced at the beginning, I feel that the two are quite contrasting when it comes to concurrency as well.

Most programming languages provide "parallelism" as part of a library or framework. Therefore, in many cases, one must design "concurrency" and "parallelism" without them being clearly differentiated. This is probably why misunderstandings occur, such as thinking of concurrency (relative to parallelism) as "executing multiple processes in order." However, from another perspective, there are performance benefits to be gained precisely because "parallelism" and "concurrency" are tightly coupled, as is the case with Rust.

On the other hand, Go comes standard with "parallelism" in its runtime, clearly separating it from "concurrency" and making them loosely coupled to increase the flexibility of "concurrency" itself. In that sense, Go and Rust are in a trade-off relationship. Well, I don't think there's such a thing as an ultimate choice like "choose either Go or Rust" (laughs).

So...

If you want to study concurrency in Go, start by reading "Concurrency in Go" first.

https://www.amazon.co.jp/dp/4621300253

脚注
  1. As for Rust, I'm currently at a standstill. Rust is a bit heavy for an individual to write small bits of code in their spare time. ↩︎

GitHubで編集を提案

Discussion