View profile

Concurrency in Go #3 - sync.Cond, sync.Once - Software Shots

Concurrency in Go #3 - sync.Cond, sync.Once - Software Shots
By Karn • Issue #14 • View online
Hey there, wish you a very Happy Independence Day 🧡
As promised I’ll go over some more types from the sync package: Cond, and Once. This is a fun one, make sure you read it through.

Cond
The best definition of any Go type can be found in its comments/go-doc. If it’s not there you’re looking at a bad library.
Cond implements a condition variable, a rendezvous point for goroutines waiting for or announcing the occurrence of an event.
Each Cond has an associated Locker L (often a *Mutex or *RWMutex), which must be held when changing the condition and when calling the Wait method.
A Cond must not be copied after first use.
Very often you’ll want to wait for one of these signals before continuing execution on a goroutine. If we were to accomplish this without the Cond type, one naive approach of doing this is an infinite loop:
However, this would consume all cycles of 1 core. To fix that, we could introduce a time.Sleep:
This is better, but it’s still inefficient, you have to figure out how long to sleep for:
  • too long: you’re forcefully degrading performance.
  • too short: you’re unnecessarily consuming too much CPU time.
Here comes in Cond. It allows a goroutine to efficiently go to sleep until it was signaled to wake and check its condition.
Let’s go over an interesting example to understand Cond better. A goroutine that is waiting for a signal, and a goroutine that is sending signals. Say we have a queue of fixed length 2, and 5 items we want to push into the queue. We want to enqueue item as soon as there is room.
Cond example
Cond example
As you can see, the program successfully adds all 5 items to the queue and before it has a chance to dequeue the last 2 items. You can also notice the Signal Method. This is one of the two methods that the Cond type provides for notifying goroutines blocked on a Wait. The other method is Broadcast.
Signal finds the goroutine that’s been waiting for the longest and notifies that, whereas Broadcast sends a signal to all goroutines that are waiting. We can trivially reproduce the behavior of channels but Broadcast would be more difficult. Let me know if you want me to go more into Broadcast and I’ll put one extra Software Shot during the coming week.
Once
What do you think the output of this will be?
Once example
Once example
It is tempting to say the result is 100, but I’m sure you have noticed the sync.Once variable. The output is:
Count: 1
As the name implies, sync.Once is a type that utilizes some sync primitives internally to ensure that only one call to Do ever calls the function passed in, even on different goroutines.
Also note sync.Once only counts the number of times Do is called, not how many times unique functions passed into Do are called.
Thats about it for this shot. Have a killer week ahead. 🍺
Did you enjoy this issue?
Karn
By Karn

I build and create things. As of now, I work as a Software Engineer at SendX/SendPost.

If you don't want these updates anymore, please unsubscribe here.
If you were forwarded this newsletter and you like it, you can subscribe here.
Powered by Revue
Gyan Karn, Delhi, India - 110039