Concurrency in Go: Tools and Techniques for Developers
Rate it:
Open Preview
Read between August 20 - September 1, 2019
14%
Flag icon
channels use memory access synchronization to operate, therefore they can only be slower.
14%
Flag icon
Coroutines are simply concurrent subroutines (functions, closures, or methods in Go) that are nonpreemptive — that is, they cannot be interrupted.
17%
Flag icon
Context switching in software is comparatively much, much cheaper. Under a software-defined scheduler, the runtime can be more selective in what is persisted for retrieval, how it is persisted, and when the persisting need occur.
20%
Flag icon
You’ll notice that we always call Unlock within a defer statement. This is a very common idiom when utilizing a Mutex to ensure the call always happens, even when panicing. Failing to do so will probably cause your program to deadlock.
22%
Flag icon
c.Signal()
25%
Flag icon
sync.Once only counts the number of times Do is called, not how many times unique functions passed into Do are called.
28%
Flag icon
You don’t often see unidirectional channels instantiated, but you’ll often see them used as function parameters and return types, which is very useful, as we’ll see. This is possible because Go will implicitly convert bidirectional channels to unidirectional channels when needed.
29%
Flag icon
The second return value is a way for a read operation to indicate whether the read off the channel was a value generated by a write elsewhere in the process, or a default value generated from a closed channel.
31%
Flag icon
if a buffered channel is empty and has a receiver, the buffer will be bypassed and the value will be passed directly from the sender to the receiver.
32%
Flag icon
reading from a nil channel will block
32%
Flag icon
writes to a nil channel will also block.
34%
Flag icon
The time.After function takes in a time.Duration argument and returns a channel that will send the current time after the duration you provide it. This offers a concise way to time out in select statements.
56%
Flag icon
Chunking is faster because bytes.Buffer must grow its allocated memory to accommodate the bytes it must store. For various reasons, growing memory is expensive; therefore, the less times we have to grow, the more efficient our system as a whole will perform.
62%
Flag icon
they recommend you define a custom key-type in your package. As long as other packages do the same, this prevents collisions within the Context.
63%
Flag icon
The data should help decorate operations, not drive them. If your algorithm behaves differently based on what is or isn’t included in its Context, you have likely crossed over into the territory of optional parameters.
63%
Flag icon
Sometimes it’s clear that something should not be stored in a context, as it is with API server connections, but sometimes it’s not so clear. What about an authorization token? It’s immutable, and it’s likely a slice of bytes, but won’t the receivers of this data use it to determine whether to field the request? Does this data belong in a context?
88%
Flag icon
Go models concurrency using a fork-join model. In a fork-join paradigm, tasks are likely dependent on one another, and it turns out naively splitting them among processors will likely cause one of the processors to be underutilized. Not only that, but it can also lead to poor cache locality as tasks that require the same data are scheduled on other processors.
89%
Flag icon
This is the unrealized join point in step three of our algorithm. Because of this, it pops work off the tail of its own queue, here fib(2)
93%
Flag icon
the Go team recommends running a build of your application built with the race flag under real-world load. This increases the probability of finding races by virtue of increasing the probability that more code is exercised.