Skip to content

Commit

Permalink
Remove lock from Parallel
Browse files Browse the repository at this point in the history
It isn't parallel when you run each function between a mutex
  • Loading branch information
bahlo committed Aug 27, 2015
1 parent 4421252 commit 7c8b84e
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 60 deletions.
17 changes: 2 additions & 15 deletions concurrency.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,15 @@ import (
)

// Parallel runs a given function n times concurrently
// The function get's called with it's number (0-n) for logging purposes
// NOTE: Please set runtime.GOMAXPROCS to runtime.NumCPU()
func Parallel(n int, fn func(int)) {
func Parallel(n int, fn func()) {
var wg sync.WaitGroup
wg.Add(n)
defer wg.Wait()

var m sync.Mutex
counter := 0

for i := 0; i < n; i++ {
go func() {
// Lock mutex to prevent multiple functions with the same index
m.Lock()

// Run function
fn(counter)

// Increment counter
counter++

m.Unlock()
fn()
wg.Done()
}()
}
Expand Down
59 changes: 14 additions & 45 deletions concurrency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ import (
"fmt"
"sync"
"testing"
"time"
)

func TestParallel(t *testing.T) {
var wg sync.WaitGroup
var m sync.Mutex

counter := 0

wg.Add(2)
go Parallel(2, func(n int) {
go Parallel(2, func() {
m.Lock()
counter++
m.Unlock()
wg.Done()
})
wg.Wait()
Expand All @@ -24,51 +26,18 @@ func TestParallel(t *testing.T) {
}
}

func TestParallelCounter(t *testing.T) {
var wg sync.WaitGroup

sum := 0
wg.Add(4)
go Parallel(4, func(n int) {
sum += n
wg.Done()
})

wg.Wait()

if sum != 6 {
t.Errorf("Expected sum to be %d, but got %d", 6, sum)
}
}

func TestParallelTiming(t *testing.T) {
// The most basic call
func ParallelExamples() {
var m sync.Mutex
counter := 0

go Parallel(4, func(n int) {
time.Sleep(time.Duration(10*n) * time.Millisecond)
m.Lock()
counter++
m.Unlock()
})

done := make(chan bool)
time.AfterFunc(25*time.Millisecond, func() {
c := 0
Parallel(4, func() {
m.Lock()
if counter != 2 {
t.Errorf("Expected counter to be %d, but got %d", 2, counter)
}
m.Unlock()
done <- true
})

<-done
}
fmt.Print(c)
c++

// The most basic call
func ParallelExamples() {
Parallel(4, func(n int) {
fmt.Print(n)
m.Unlock()
})

// Output: 0123 in any order
Expand All @@ -77,9 +46,9 @@ func ParallelExamples() {
// If you need to pass parameters to your function, just wrap it in another
// and call the superior function immeditately.
func ParallelExamples_Parameters() {
fn := func(someParam, someOtherParam string) func(int) {
return func(n int) {
fmt.Print(n, someParam, someOtherParam)
fn := func(someParam, someOtherParam string) func() {
return func() {
fmt.Print(someParam, someOtherParam)
}
}

Expand Down

0 comments on commit 7c8b84e

Please sign in to comment.