count / display the number of active goroutines - concurrency

I have a queue and a function that does both dequeueing and enqueueing. I want to make sure that the right amount of goroutines operate on the queue, as long as there is something in the list.
This is the code I am using, but I was wondering if there is a way of printing the amount of currently active goroutines
Link to playground
var element int
func deen(queue chan int) {
element := <-queue
fmt.Println("element is ", element)
if element%2 == 0 {
fmt.Println("new element is ", element)
queue <- (element*100 + 11)
queue <- (element*100 + 33)
}
}
func main() {
queue := make(chan int, 10)
queue <- 1
queue <- 2
queue <- 3
queue <- 0
for len(queue) != 0 {
for i := 0; i < 2; i++ {
go deen(queue)
}
}
fmt.Scanln()
fmt.Println("list is has len", len(queue)) //this must be 0
}

There's runtime.NumGoroutine but you're approaching this wrong.
Your loops will keep spawning goroutines.
this will unnecessarily burn cpu cycles because of the for loop.
One approach is to use a sync.WaitGroup.
func deen(wg *sync.WaitGroup, queue chan int) {
for element := range queue {
fmt.Println("element is ", element)
if element%2 == 0 {
fmt.Println("new element is ", element)
wg.Add(2)
queue <- (element*100 + 11)
queue <- (element*100 + 33)
}
wg.Done()
}
}
func main() {
var wg sync.WaitGroup
queue := make(chan int, 10)
queue <- 1
queue <- 2
queue <- 3
queue <- 0
for i := 0; i < 4; i++ {
wg.Add(1)
go deen(&wg, queue)
}
wg.Wait()
close(queue)
fmt.Println("list len", len(queue)) //this must be 0
}
playground
--- old buggy version with a race in it ---
func deen(wg *sync.WaitGroup, queue chan int) {
for element := range queue {
wg.Done()
fmt.Println("element is ", element)
if element%2 == 0 {
fmt.Println("new element is ", element)
wg.Add(2)
queue <- (element*100 + 11)
queue <- (element*100 + 33)
}
}
}
func main() {
var wg sync.WaitGroup
queue := make(chan int, 10)
queue <- 1
queue <- 2
queue <- 3
queue <- 0
for i := 0; i < 4; i++ {
wg.Add(1)
go deen(&wg, queue)
}
wg.Wait()
close(queue)
fmt.Println("list is has len", len(queue)) //this must be 0
}
playground

Related

comparing nested slices while ignoring order

In a test function, there is a case where nested slices should be compared.
Say I have two varibles like the following:
want := [][]string{{"bat"},{"nat","tan"},{"ate","eat","tea"}}
got := [][]string{{"eat","tea","ate"},{"tan","nat"},{"bat"}}
How can compare them?
First, I used reflect.DeepEqual which was wrong, I also tried go-cmp:
t.Run(tt.name, func(t *testing.T) {
opt := cmpopts.SortSlices(func (a, b []int) bool {
// not sure what to write
})
if got := groupAnagrams(tt.args.strs); !cmp.Equal(got, tt.want, opt) {
t.Errorf("groupAnagrams() = %v, want %v", got, tt.want)
}
})
Sort the inner slices:
for _, s := range want { sort.Strings(s) }
for _, s := range got { sort.Strings(s) }
Sort the outer slices:
sortOuter(want)
sortOuter(got)
where sortOuter is a the function:
func sortOuter(s [][]string) {
sort.Slice(s, func(a, b int) bool {
sa := s[a]
sb := s[b]
n := len(sa)
if n > len(sb) {
n = len(sb)
}
for i := 0; i < n; i++ {
if sa[i] != sb[i] {
return sa[i] < sb[i]
}
}
return len(sa) < len(sb)
})
}
Compare:
fmt.Println(reflect.DeepEqual(got, want))
https://go.dev/play/p/SjN8gLmotjd
You can sort inner slices using sort.Slice as below and check if outer slices are equal using testify assert.ElementsMatch:
func TestXxx(t *testing.T) {
// Slices
want := [][]string{{"bat"}, {"nat", "tan"}, {"ate", "eat", "tea"}}
got := [][]string{{"eat", "tea", "ate"}, {"tan", "nat"}, {"bat"}}
// Running tests
t.Run("test", func(t *testing.T) {
// Sorting got inners
for _, inner := range got {
sort.Slice(inner, func(i, j int) bool {
return inner[i] < inner[j]
})
}
// Sorting want inners
for _, inner := range want {
sort.Slice(inner, func(i, j int) bool {
return inner[i] < inner[j]
})
}
// Match
assert.ElementsMatch(t, got, want)
})
}
ElementsMatch:
ElementsMatch asserts that the specified listA(array, slice...) is equal to specified listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, the number of appearances of each of them in both lists should match.
assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])

Passing array into function, want the original unmodified array afterward

I have a function that, as a side-effect, mutates an array that's passed in:
fun do_something (n: int, v: bool array) =
let
val i = ref 0
val count = ref 0
in while !i < n do
( if Array.sub (v, !i) then
Array.update (v, !i, false)
else
(count := !count + 1);
i := !i + 1
);
!count
end
When the function has ended I want the array to have its original contents again. How can I do that?

What's the Go idiom for Python's list.pop() method?

In Python, I have the following:
i = series.index(s) # standard Python list.index() function
tmp = series.pop(i)
blah = f(tmp)
series.append(tmp)
In converting this to Go, I am looking for a similar way of retrieving an item from a slice by index, doing something with it, then putting the original item at the end of my slice.
From here, I have arrived at the following:
i = Index(series, s) // my custom index function...
tmp, series = series[i], series[i+1:]
blah := f(tmp)
series = append(series, tmp)
But this fails at the end of lists:
panic: runtime error: slice bounds out of range
How would I idiomatically translate this slice.pop() into Go?
The "Cut" trick in the linked document does what you want:
xs := []int{1, 2, 3, 4, 5}
i := 0 // Any valid index, however you happen to get it.
x := xs[i]
xs = append(xs[:i], xs[i+1:]...)
// Now "x" is the ith element and "xs" has the ith element removed.
Note that if you try to make a one-liner out of the get-and-cut operations you'll get unexpected results due to the tricky behavior of multiple assignments in which functions are called before other expressions are evaluated:
i := 0
x, xs := xs[i], append(xs[:i], xs[i+1:]...)
// XXX: x=2, xs=[]int{2, 3, 4, 5}
You can work around by wrapping the element access operation in any function call, such as the identity function:
i := 0
id := func(z int) { return z }
x, xs := id(xs[i]), append(xs[:i], xs[i+1:]...)
// OK: x=1, xs=[]int{2, 3, 4, 5}
However, at that point it's probably more clear to use separate assignments.
For completeness, a "cut" function and its usage could look like this:
func cut(i int, xs []int) (int, []int) {
y := xs[i]
ys := append(xs[:i], xs[i+1:]...)
return y, ys
}
t, series := cut(i, series)
f(t)
series = append(series, t)
If you want to write a function that does pop() in a similar way to python then you'll have to pass in a pointer to the object so the object can be modified, as pop both returns the value and alters the list
func pop(alist *[]int) int {
f:=len(*alist)
rv:=(*alist)[f-1]
*alist=(*alist)[:f-1]
return rv
}
func main() {
n:=[]int{1,2,3,4,5}
fmt.Println(n)
last:=pop(&n)
fmt.Println("last is",last)
fmt.Printf("list of n is now %v\n", n)
You can declaretype intSlice []int and you can declare method pop() using that pointer receiver: func (l *intSlice) pop() int. Then you can call .pop() on instance of intSlice object. This becomes stylistically more similar to Python.
package main
import (
"fmt"
)
type intSlice []int
func (l *intSlice) pop() int {
length := len(*l)
lastEle := (*l)[length-1]
*l = (*l)[:length-1]
return lastEle
}
func main() {
mySlice := intSlice{1, 2, 3, 4, 5, 6}
popped := mySlice.pop()
fmt.Println(popped)
fmt.Println(mySlice)
popped = mySlice.pop()
fmt.Println(popped)
fmt.Println(mySlice)
}
Result:
6
[1 2 3 4 5]
5
[1 2 3 4]
Go Playground
I'm not sure there's a direct equivalent of "pop()" ... but you can do something like this:
A Tour of Go
Slices can be created with the built-in make function; this is how
you create dynamically-sized arrays.
The make function allocates a zeroed array and returns a slice that
refers to that array:
a := make([]int, 5) // len(a)=5
To specify a capacity, pass a third argument to make:
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4
See also:
https://blog.golang.org/go-slices-usage-and-internals
cap vs len of slice in golang
I'd do something similar to what paulsm4 suggested:
package main
import (
"fmt"
)
func main() {
a := []int{1,2,3,4,5}
i,b := pop(a)
fmt.Println(i,b) // 5 [1 2 3 4]
}
func pop(a []int) (int,[]int) {
return a[len(a)-1],a[:len(a)-1]
}
Go playground
Another option would be to create a function that takes a pointer to an int slice which modifies the argument to remove the last value and return it:
func pop(xs *[]int) int {
x := (*xs)[len(*xs)-1] // Store the last value to return.
*xs = (*xs)[:len(*xs)-1] // Remove the last value from the slice.
return x
}
For example (Go Playground):
xs := []int{1, 2, 3} // => xs=[1, 2, 3]
x := pop(&xs) // => xs=[1, 2], x=3

How to construct a loop in a list in golang

I wrote a function to find the loop in a list using golang. But I am not able to construct a loop in a list as input.
Please find below the code,
package main
import (
"container/list"
"fmt"
)
func main() {
l := list.New()
l.PushBack(0)
l.PushBack(1)
l.PushBack(2)
l.PushBack(3)
l.PushBack(4)
l.PushBack(5)
e6 := l.PushBack(6)
l.PushBack(7)
e8 :=l.PushBack(8)
e9 := l.InsertAfter(9,e8)
l.InsertBefore(e9, e6)
for e:=l.Front() ; e !=nil ; e=e.Next() {
fmt.Println(e.Value)
}
}
could anyone help me on this?
It is not possible to construct a loop using the container/list List type. The List type methods ensure that there's no loop. Because the list Element's next and previous pointers are not exported, the application cannot create a loop by modifying the elements directly.
You can define your own type to create a list with a loop:
package main
import "fmt"
type node struct {
v int
next *node
}
func main() {
// Create list with 1, 2, 3 and print.
l := &node{1, &node{2, &node{3, nil}}}
for n := l; n != nil; n = n.next {
fmt.Println(n.v)
}
// Create list with loop and print at most 100 steps down the list.
n3 := &node{3, nil}
l = &node{1, &node{2, n3}}
n3.next = l
for i, n := 0, l; n != nil && i < 100; n, i = n.next, i+1 {
fmt.Println(n.v)
}
}
playground example

go routines deadlocked even if channel was closed

I have a list, with a function that pop element from it, and another function that "receives" the popped elements. I thought that putting a close after the receiver would close the channel, but it seems that the program is deadlock before getting there. Which is the best way of doing this? Should I have another channel that detects when the pop are done?
Playground link
func pop(list *[]int, c chan int) {
if len(*list) != 0 {
result := (*list)[0]
*list = (*list)[1:]
fmt.Println("about to send ", result)
c <- result
} else {
return
}
}
func receiver(c chan int) {
result := <-c
fmt.Println("received ", result)
}
var list = []int{1, 2, 3}
func main() {
fmt.Println("Main")
c := make(chan int)
go pop(&list, c)
go pop(&list, c)
for len(list) > 0 {
receiver(c)
}
close(c) //Dosen't seem to have any effect
fmt.Println("done")
}
There are so many problems with the code, let's see.
your pop function doesn't lock when accessing the slice, so that's a data race right there.
for len(list) > 0 {} is a data race because you're accessing list while modifying it in 2 other goroutines.
for len(list) > 0 {} will never return because you have 3 items in your list but you call pop only twice.
receiver(c) errors because of #3, it tries to read from the channel but there's nothing writing to it.
One way to do it is to use one writer (pop) and multiple readers (receiver):
func pop(list *[]int, c chan int, done chan bool) {
for len(*list) != 0 {
result := (*list)[0]
*list = (*list)[1:]
fmt.Println("about to send ", result)
c <- result
}
close(c)
done <- true
}
func receiver(c chan int) {
for result := range c {
fmt.Println("received ", result)
}
}
var list = []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
func main() {
c := make(chan int)
done := make(chan bool)
go pop(&list, c, done)
go receiver(c)
go receiver(c)
go receiver(c)
<-done
fmt.Println("done")
}
playground
Always use go run -race blah.go when messing with goroutines.