DEV Community

Perm Chao
Perm Chao

Posted on • Edited on

Implement semaphore in golang by buffered channel

Cover

Getting started

1) make buffered channel

sem := make(chan int, 10)
Enter fullscreen mode Exit fullscreen mode

2) in synchronous process, send some variable to buffered channel (this step called acquire)

sem <- i
Enter fullscreen mode Exit fullscreen mode

3) in asynchronous process, release variable from buffered channel (this step called release)

<- sem
Enter fullscreen mode Exit fullscreen mode

Result from log

start   process [9]
start   process [0]
start   process [7]
start   process [6]
start   process [3]
start   process [2]
start   process [4]
start   process [8]
start   process [1]
start   process [5] <- 10 processes start concurrency
end     process [0]      0.0001 seconds
start   process [10] <- process 10 start after process 0 end
end     process [2]      4.0014 seconds
end     process [1]      4.0012 seconds
start   process [12]
start   process [11] <- process 11, 12 start after process 1, 2 end
end     process [3]      5.0011 seconds
start   process [13]
end     process [4]      0.0001 seconds
start   process [14]
end     process [5]      6.0014 seconds
start   process [15]
end     process [6]      1.0011 seconds
start   process [16]
end     process [7]      8.0013 seconds
start   process [17]
...
Enter fullscreen mode Exit fullscreen mode

Remark

Standard package
golang.org/x/sync/semaphore


Code

package main

import (
    "fmt"
    "math/rand"
    "time"
)

const (
    MAX_CONCURRENT     = 10   // Allow max concurrent
    TOTAL_PROCESSES    = 1000 // Total loop count
    MAX_RANDOM_SECONDS = 20
)

func main() {
    sem := make(chan int, MAX_CONCURRENT)
    for i := range TOTAL_PROCESSES {
        sem <- i // *** send i to buffered channel. If channel sem full, it blocked for loop.
        go func(i int) {
            start := time.Now()
            fmt.Printf("start\tprocess\t[%d]\n", i)
            defer func() {
                // <- sem will release a value, so sem channel will available for next value
                fmt.Printf("end\tprocess\t[%d]\t %.4f seconds\n", <-sem, time.Since(start).Seconds())
            }()
            iv := rand.Intn(MAX_RANDOM_SECONDS) * int(time.Second)
            time.Sleep(time.Duration(iv))
        }(i)
    }
}
Enter fullscreen mode Exit fullscreen mode
start   process [0]
start   process [9]
start   process [5]
start   process [6]
start   process [7]
start   process [8]
start   process [2]
start   process [1]
start   process [3]
start   process [4]
start   process [10]
end     process [0]      3.0013 seconds
start   process [11]
end     process [1]      2.0012 seconds
start   process [12]
end     process [2]      6.0012 seconds
end     process [3]      9.0012 seconds
start   process [13]
end     process [4]      5.0008 seconds
start   process [14]
end     process [5]      12.0012 seconds
end     process [6]      12.0012 seconds
start   process [16]
start   process [15]
start   process [17]
end     process [7]      14.0012 seconds
end     process [8]      16.0012 seconds
end     process [9]      16.0012 seconds
start   process [19]
end     process [10]     0.0001 seconds
start   process [20]
start   process [18]
end     process [11]     17.0012 seconds
start   process [21]
end     process [12]     18.0002 seconds
start   process [22]
end     process [14]     8.0012 seconds
end     process [13]     4.0010 seconds
start   process [24]
start   process [23]
end     process [15]     15.0011 seconds
start   process [25]
start   process [26]
end     process [16]     13.0011 seconds
end     process [17]     15.0005 seconds
start   process [27]
end     process [18]     0.0000 seconds
start   process [28]
end     process [19]     5.0010 seconds
end     process [20]     4.0011 seconds
start   process [29]
start   process [30]
end     process [21]     2.0005 seconds
end     process [22]     12.0011 seconds
start   process [31]
start   process [32]
end     process [23]     6.0002 seconds
start   process [33]
end     process [24]     1.0002 seconds
start   process [34]
end     process [25]     9.0011 seconds
start   process [35]
end     process [26]     1.0002 seconds
start   process [36]
end     process [27]     12.0011 seconds
start   process [37]
end     process [28]     3.0007 seconds
start   process [38]
end     process [29]     13.0011 seconds
start   process [39]
end     process [30]     19.0012 seconds
start   process [40]
end     process [31]     8.0010 seconds
start   process [41]
end     process [32]     8.0011 seconds
start   process [42]
end     process [33]     8.0001 seconds
start   process [43]
end     process [34]     11.0010 seconds
end     process [35]     13.0001 seconds
start   process [45]
start   process [44]
end     process [36]     2.0009 seconds
start   process [46]
end     process [37]     1.0002 seconds
start   process [47]
end     process [38]     8.0011 seconds
start   process [48]
end     process [39]     2.0011 seconds
start   process [49]
end     process [40]     4.0011 seconds
start   process [50]
end     process [41]     6.0011 seconds
start   process [51]
start   process [52]
end     process [42]     19.0011 seconds
end     process [43]     15.0011 seconds
start   process [53]
end     process [44]     0.0000 seconds
start   process [54]
end     process [45]     17.0004 seconds
start   process [55]
end     process [46]     19.0006 seconds
start   process [56]
start   process [57]
end     process [47]     15.0011 seconds
end     process [48]     3.0011 seconds
start   process [58]
end     process [49]     17.0011 seconds
start   process [59]
end     process [50]     18.0011 seconds
start   process [60]
end     process [51]     0.0001 seconds
start   process [61]
end     process [52]     11.0001 seconds
end     process [53]     18.0004 seconds
start   process [63]
start   process [62]
end     process [54]     19.0011 seconds
start   process [64]
start   process [65]
end     process [55]     19.0002 seconds
end     process [56]     16.0006 seconds
start   process [66]
end     process [57]     11.0001 seconds
start   process [67]
end     process [58]     12.0001 seconds
start   process [68]
end     process [59]     18.0011 seconds
start   process [69]
end     process [60]     9.0002 seconds
start   process [70]
end     process [61]     6.0011 seconds
start   process [71]
end     process [63]     7.0006 seconds
end     process [62]     8.0011 seconds
start   process [73]
start   process [72]
end     process [64]     13.0011 seconds
start   process [74]
end     process [65]     15.0006 seconds
start   process [75]
end     process [66]     17.0001 seconds
start   process [76]
end     process [67]     3.0002 seconds
start   process [77]
end     process [68]     15.0011 seconds
start   process [78]
start   process [79]
end     process [69]     14.0007 seconds
end     process [70]     6.0006 seconds
end     process [71]     11.0012 seconds
start   process [81]
start   process [80]
end     process [72]     11.0011 seconds
start   process [82]
end     process [73]     4.0003 seconds
start   process [83]
end     process [74]     11.0008 seconds
end     process [75]     15.0011 seconds
start   process [85]
start   process [84]
end     process [76]     2.0011 seconds
start   process [86]
end     process [77]     6.0009 seconds
start   process [87]
end     process [78]     1.0011 seconds
start   process [88]
end     process [79]     6.0009 seconds
start   process [89]
end     process [80]     6.0011 seconds
end     process [81]     11.0008 seconds
start   process [91]
start   process [90]
start   process [92]
end     process [82]     18.0011 seconds
end     process [83]     16.0012 seconds
start   process [93]
end     process [84]     4.0002 seconds
start   process [94]
end     process [85]     9.0011 seconds
start   process [96]
start   process [95]
start   process [97]
end     process [86]     11.0003 seconds
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.