Learn what sync.Cond is

Overview

This repo is not a library. It is a reference implementation of "hint" for the programmers who are trying to understand how sync.Cond works, how it is used in the real world.

I'll leave a brief explanation in this README, but I would strongly recommend you to read my full article to get better understanding instead of just looking at this repository.

This repository contains a working code which implements a size-limited-queue. First, let me describe the spec of it:

  • The queue can contain only int values.
  • The queue supports Push and Pop. Like the common queue data structure, the order is FIFO.
  • The queue supports size capacity feature. The queue can contain elements up to the capacity.
  • When trying to push an element to the queue when the queue is full, it blocks until it gets at least a space.
  • When trying to pop an element from the queue when the queue is empty, it blocks until it gets at least an element.

There are three implementations described below:

slqueue.go has simpler implementation at the old revision. 176eb78

single_thread_slqueue.go

single_thread_slqueue.go

It works basically, but doesn't work correctly under multithread environment. The length check in Push / Pop and queue manipulation (append / moving the queue head to pop) must be atomic, but this implementation does not consider it. As a result,

  • Queue capacity is 10, now the Queue length is 9
  • Goroutine A and B tries to push an value
    • A checks the queue capacity, then it is 9
    • At almost the same time, B checks the queue capacity, then it is 9 because A still have not finished the queue manipulation (append)
    • A appends an element, now the queue length is 10
    • B appends an element, now the queue length is 11 <- violates the queue spec!

I implemented single_thread_slqueue.go to compare it with upcoming mutex_slqueue.go.

mutex_slqueue.go

mutex_slqueue.go

This uses sync.Mutex to make the queue length check and queue manipulation atomic. This actually works following all the spec, but the problem is its inefficiency.

func (s *MutexQueue) Push(i int) {
	s.mu.Lock()
	for len(s.queue) == s.capacity { // 1
		s.mu.Unlock()
		runtime.Gosched()
		s.mu.Lock()
	}

	s.queue = append(s.queue, i)
	s.mu.Unlock()
}

See 1 in the code. Because of the spec When trying to push an element to the queue when the queue is full, it blocks until it gets at least a space, it needs spin (for-loop) to achieve it. However, spin is usually inefficient. Using sync.Cond, it can be improved to get more efficient.

slqueue.go - simple

slqueue.go

This uses sync.Cond to make mutex implementation better. See the implementation:

func (s *SizeLimitedQueue) Push(i int) {
	s.cond.L.Lock()
	for len(s.queue) == s.capacity { // 1
		s.cond.Wait() // 2
	}

	s.queue = append(s.queue, i)

	s.cond.Broadcast() // 3
	s.cond.L.Unlock()
}

func (s *SizeLimitedQueue) Pop() int {
	s.cond.L.Lock()
	for len(s.queue) == 0 {
		s.cond.Wait()
	}

	ret := s.queue[0]
	s.queue = s.queue[1:]
	s.cond.Broadcast()
	s.cond.L.Unlock()

	return ret
}

When trying to Push, it first check the length (at 1) then if the condition is not met, call cond.Wait() (at 2) . In the wait, runtime will suspend the waiting goroutine and waits for the "notification" on the cond. When a goroutine calls cond.Broadcast(), the cond is notified - waiting goroutines are waken up then goes to the top of for-loop.

This has an advantage because it does not require spins.

slqueue.go - improved

slqueue.go

On the above slqueue.go, some optimizations are applied. They are described more specifically on my article.

For readers

I'm quite sure this README is not enough to understand sync.Cond. This is just a brief "summary".

To understand sync.Cond better, I'd say you have to understand a synchronization primitive "Condition Variable" in POSIX. sync.Cond is actually just a Go version of it.

I described what "Condition Variable" is, and the detailed description of above code, also some supplementary information about it in my article. I would recommend reading it with the actual source code in this repository.

If you find this repo helpful to learn sync.Cond, please leave a star!

Owner
Hidetatsu Yaginuma
Hidetatsu loves infrastructures, database, concurrent programming, transactions, distributed systems
Hidetatsu Yaginuma
Similar Resources

Automatic sync from IMDb to Trakt (watchlist, lists, ratings and history) using GitHub actions

imdb-trakt-sync GoLang app that can sync IMDb and Trakt user data - watchlist, ratings and lists. For its data needs, the app is communicating with th

Jan 2, 2023

grafana-sync Keep your grafana dashboards in sync.

grafana-sync Keep your grafana dashboards in sync. Table of Contents grafana-sync Table of Contents Installing Getting Started Pull Save all dashboard

Dec 14, 2022

keep track of things you learn / discover everyday!

keep track of things you learn / discover everyday!

🗄 Personal Archive Personal-Archive keeps track of things you learn / discover everyday! 💡 Why I face tons of articles every day. Via googling or RS

May 23, 2022

Learn how to write webapps without a framework in Go.

This is an easy to understand example based tutorial aimed at those who know a little of Go and nothing of webdev and want to learn how to write a webserver in Go. You will create a to do list application as you advance the chapters.

Dec 28, 2022

Learn Go with test-driven development

Learn Go with test-driven development

Learn Go with Tests Art by Denise Formats Gitbook EPUB or PDF Translations 中文 Português 日本語 한국어 Support me I am proud to offer this resource for free,

Jan 1, 2023

Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.

Learn how to design large-scale systems. Prep for the system design interview.  Includes Anki flashcards.

English ∙ 日本語 ∙ 简体中文 ∙ 繁體中文 | العَرَبِيَّة‎ ∙ বাংলা ∙ Português do Brasil ∙ Deutsch ∙ ελληνικά ∙ עברית ∙ Italiano ∙ 한국어 ∙ فارسی ∙ Polski ∙ русский язы

Jan 9, 2023

Introduction to beginners learn to go

For-learning-Go-Tutorial 准备写一本Go的书针对初学者快速入门开发和使用go! 学习Go语言需要去了解Go的特性,然后在深入的去实践,如果你想使用Go语言写出Go味道的程序,那么你就需要付出努力去实践了! 先来了解下Go语言为何创造出来的历史吧,Go 语言是由谷歌公司在 20

Dec 25, 2022

a simple shitty project for learn more about websockets

video-transmission A simple shitty project for learn more about websockets. For run this you only need to have docker in your computer and then execut

Mar 29, 2022

simpleChatInGo - This is a simple chat that i made for fun asnd learn more about websocket

simpleChatInGo - This is a simple chat that i made for fun asnd learn more about websocket

simpleChatInGo This is a simple chat that i made for fun asnd learn more about websocket deploy For deploy this you only need to run the command : $ d

Sep 21, 2022

My old liquidation bot - doesn't compile, just learn from it

Open sourced liquidation bot So this is my liquidation bot from fall 2020 - its completely outdated and I removed my private key, relevant addrs, so y

Dec 22, 2022

A repository for the X-Team community to collaborate and learn solutions to most coding challenges to help prepare for their interviews.

A repository for the X-Team community to collaborate and learn solutions to most coding challenges to help prepare for their interviews.

Community Coding Challenge Handbook This repository focuses on helping X-Teamers and community members to thrive through coding challenges offering so

Sep 6, 2022

Building a shoe store with golang to learn more about this language :)

shoestore-go Building a shoe store with golang to learn more about this language :) TODO Create a basic webpage with the pages: home : to show homepag

Jan 24, 2022

This project used to learn golang and try to bypass AV

This project used to learn golang and try to bypass AV

sucksAV This project used to learn golang and try to bypass AV 描述 基于Golang开发的BypassAV,采取的shellcode分离技术,将shellcode注入到图片中,通过加载器进行加载,使用Golang动态加载技术 需要使用第

Nov 19, 2022

A very simple rate limiter in go, made as a learning project to learn go and rate limiting patterns!

A very simple rate limiter in go, made as a learning project to learn go and rate limiting patterns!

rate-limiter-go A very simple rate limiter in go, made as a learning project to learn go and rate limiting patterns! Demo: Running the project: To exe

Jun 1, 2022

Application to learn and demo Tekton pipelines

Tekton sample Application to learn and demo Tekton pipelines Building $ go test ./pkg/api && go build Running it locally $ podman-compose up --force-r

Oct 28, 2021

This is a template project to help beginners learn, or to help developers develop some interesting small projects

This is a template project to help beginners learn, or to help developers develop some interesting small projects

This is a template project to help beginners learn, or to help developers develop some interesting small projects

Dec 13, 2022

A simple memory database. It's nothing but a homework to learn primary datastruct of golang.

A simple memory database. It's nothing but a homework to learn primary datastruct of golang.

Nov 8, 2021

The purpose of this project is to learn about go-swagger.

learn-go-swagger The purpose of this project is to learn about go-swagger. Requirements Go go-swagger Setup Run ./scripts/gen-swagger to generate swag

Nov 20, 2021

Learn REST API with Go

web-w-go Enviroment Requirement go version go1.17.3 linux/amd64 Using go module github.com/cosmtrek/air - Auto reload VS Code Linux OS Go-gin framewor

Dec 26, 2021
Goal: Learn a Go plotting library and track my Electricity costs
Goal: Learn a Go plotting library and track my Electricity costs

Goal: Learn a Go plotting library and track my Electricity costs Findings https:

Jan 2, 2022
A component for sync services between Nacos and Kubernetes.

简介 该项目用于同步Kubernetes和Nacos之间的服务信息。 目前该项目仅支持 Kubernetes Service -> Nacos Service 的同步 TODO 增加高性能zap的logger 增加 Nacos Service -> Kubernetes Service 的同步 监听

May 16, 2022
Flux is a tool for keeping Kubernetes clusters in sync with sources of configuration, and automating updates to configuration when there is new code to deploy.
Flux is a tool for keeping Kubernetes clusters in sync with sources of configuration, and automating updates to configuration when there is new code to deploy.

Flux is a tool for keeping Kubernetes clusters in sync with sources of configuration (like Git repositories), and automating updates to configuration when there is new code to deploy.

Jan 8, 2023
A CLI to sync configmaps and secrets in a kubernetes cluster

kube-sync Kube Sync is a CLI application to copy/sync configmaps and secrets from one namespace to another. Motivation While working with kubernetes,

Oct 15, 2022
ArgoCD is widely used for enabling CD GitOps. ArgoCD internally builds manifest from source data in Git repository, and auto-sync it with target clusters.
ArgoCD is widely used for enabling CD GitOps. ArgoCD internally builds manifest from source data in Git repository, and auto-sync it with target clusters.

ArgoCD Interlace ArgoCD is widely used for enabling CD GitOps. ArgoCD internally builds manifest from source data in Git repository, and auto-sync it

Dec 14, 2022
Kubernetes Operator to sync secrets between different secret backends and Kubernetes

Vals-Operator Here at Digitalis we love vals, it's a tool we use daily to keep secrets stored securely. We also use secrets-manager on the Kubernetes

Nov 13, 2022
Help developer to sync between local file and remote apollo portal web since portal web is so messy to use

apollo-synchronizer Help developer to sync between local file and remote apollo portal web since portal web is so messy to use Features download names

Oct 27, 2022
To copy a secret to another namespace and sync it up-to-date

Secret Mirror Operator This kubebuilder-based Kubernetes operator copies a Secret to another namespace and synchronizes it with the custom resource Se

Jul 20, 2022
A simple tool to sync your etcd cluster to PostgreSQL in realtime.

etcd-postgresql-syncer A simple tool to sync your etcd cluster to PostgreSQL in realtime. It sets up a watcher on etcd and commits all changes to Post

Jan 20, 2022
Flux prometheus grafana-example - A tool for keeping Kubernetes clusters in sync with sources ofconfiguration
Flux prometheus grafana-example - A tool for keeping Kubernetes clusters in sync with sources ofconfiguration

Flux is a tool for keeping Kubernetes clusters in sync with sources of configuration (like Git repositories), and automating updates to configuration when there is new code to deploy.

Feb 1, 2022