Skip to content

Commit

Permalink
feat(coroutine): Added Concurrent and Parallel (#74)
Browse files Browse the repository at this point in the history
* feat(coroutine): Added `Concurrent` and `Parallel`

Signed-off-by: Flc゛ <[email protected]>

* feat(coroutine): Added `Concurrent` and `Parallel`

Signed-off-by: Flc゛ <[email protected]>

* feat(coroutine): Added `Concurrent` and `Parallel`

Signed-off-by: Flc゛ <[email protected]>

---------

Signed-off-by: Flc゛ <[email protected]>
  • Loading branch information
flc1125 authored Jan 25, 2024
1 parent b5451dd commit d3d1bdc
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 0 deletions.
25 changes: 25 additions & 0 deletions coroutine/concurrent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package coroutine

import "sync"

func Concurrent(limit int, tasks ...func()) {
var (
wg sync.WaitGroup
ch = make(chan struct{}, limit)
)
defer close(ch)
wg.Add(len(tasks))

for _, task := range tasks {
ch <- struct{}{}
go func(task func()) {
defer func() {
<-ch
wg.Done()
}()
task()
}(task)
}

wg.Wait()
}
39 changes: 39 additions & 0 deletions coroutine/concurrent_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package coroutine

import (
"bytes"
"sync"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestConcurrent(t *testing.T) {
var (
start = time.Now()
buffer bytes.Buffer
mu sync.Mutex
)

Concurrent(2, func() {
time.Sleep(1 * time.Second)
mu.Lock()
defer mu.Unlock()
buffer.WriteString("1")
}, func() {
time.Sleep(2 * time.Second)
mu.Lock()
defer mu.Unlock()
buffer.WriteString("2")
}, func() {
time.Sleep(3 * time.Second)
mu.Lock()
defer mu.Unlock()
buffer.WriteString("3")
})

assert.Equal(t, "123", buffer.String())
assert.True(t, time.Since(start) > 4*time.Second)
assert.True(t, time.Since(start) < 6*time.Second)
}
17 changes: 17 additions & 0 deletions coroutine/parallel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package coroutine

import "sync"

func Parallel(tasks ...func()) {
var wg sync.WaitGroup
wg.Add(len(tasks))

for _, task := range tasks {
go func(task func()) {
defer wg.Done()
task()
}(task)
}

wg.Wait()
}
38 changes: 38 additions & 0 deletions coroutine/parallel_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package coroutine

import (
"bytes"
"sync"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestParallel(t *testing.T) {
var (
start = time.Now()
buffer bytes.Buffer
mu sync.Mutex
)

Parallel(func() {
time.Sleep(1 * time.Second)
mu.Lock()
defer mu.Unlock()
buffer.WriteString("1")
}, func() {
time.Sleep(2 * time.Second)
mu.Lock()
defer mu.Unlock()
buffer.WriteString("2")
}, func() {
time.Sleep(3 * time.Second)
mu.Lock()
defer mu.Unlock()
buffer.WriteString("3")
})

assert.Equal(t, "123", buffer.String())
assert.True(t, time.Since(start) < 4*time.Second)
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ require (
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sync v0.4.0 // indirect
golang.org/x/sys v0.16.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect
google.golang.org/grpc v1.60.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,17 @@ golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 h1:YJ5pD9rF8o9Qtta0Cmy9rdBwkSjrTCT6XTiUQVOtIos=
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU=
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
Expand Down

0 comments on commit d3d1bdc

Please sign in to comment.