Skip to content

Latest commit

 

History

History
85 lines (72 loc) · 1.28 KB

barrier.md

File metadata and controls

85 lines (72 loc) · 1.28 KB

A set of concurrent work must complete first, before the next batch of concurrent work can happen.

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var mu sync.Mutex
	cond := sync.NewCond(new(sync.Mutex))

	var i int
	condition1 := func() bool {
		return i == 3
	}

	increment := func() {
		fmt.Println("increment")
		time.Sleep(1 * time.Second)
		mu.Lock()
		defer mu.Unlock()
		i++
		if i == 3 {
			cond.Broadcast()
		}
	}

	condition2 := func() bool {
		return i == 0
	}

	decrement := func() {
		fmt.Println("decrement")
		time.Sleep(1 * time.Second)
		mu.Lock()
		defer mu.Unlock()
		i--
		if i == 0 {
			cond.Broadcast()
		}
	}

	work := func(c *sync.Cond, wg *sync.WaitGroup) {

		fmt.Println("start")
		cond.L.Lock()
		go increment()
		for !condition1() {
			fmt.Println("start work 1")
			cond.Wait()
			fmt.Println("do work")
		}
		cond.L.Unlock()
		wg.Done()

		wg.Add(1)
		cond.L.Lock()
		go decrement()
		for !condition2() {
			fmt.Println("start work 2")
			cond.Wait()
			fmt.Println("do work 2")
		}
		cond.L.Unlock()
		fmt.Println("end")
		wg.Done()

	}

	var wg sync.WaitGroup
	for i := 0; i < 3; i++ {
		wg.Add(1)
		go work(cond, &wg)
	}
	wg.Wait()
	fmt.Println("exiting")
}

References