tour: Concurrent tree comparison: Add mutexes and waitGroup.
authorsgf <sgf.dma@gmail.com>
Wed, 11 May 2022 15:04:21 +0000 (18:04 +0300)
committersgf <sgf.dma@gmail.com>
Wed, 11 May 2022 15:04:21 +0000 (18:04 +0300)
Add mutexes for syncing prints from go routines walking both trees.
Add wait group for waiting for print from last go routine to complete.

tree/tree.go

index c272961..4f5a0eb 100644 (file)
@@ -5,48 +5,57 @@ import (
     "strconv"
     //"bytes"
     "strings"
+    "sync"
+    //"time"
 
     "golang.org/x/tour/tree"
 )
 
+var mu sync.Mutex
+var wg sync.WaitGroup
+
 // Walk walks the tree t sending all values
 // from the tree to the channel ch.
 func Walk(m, wm string, t *tree.Tree, ch chan int) {
     if t == nil {
         return
     }
-    fmt.Printf("[%v] node %v start\n", m, t.Value)
+    //fmt.Printf("[%v] node %v start\n", m, t.Value)
     Walk(m, wm, t.Left, ch)
-    fmt.Printf("[%v] node %v Left done\n", m, t.Value)
+    //fmt.Printf("[%v] node %v Left done\n", m, t.Value)
     waiting := false
 
 out:
     for {
+        mu.Lock()
         select {
         case ch <- t.Value:
             if waiting {
-                fmt.Println()
+                //fmt.Println()
                 waiting = false
             }
-            fmt.Printf("[%v] node %v sent\n", m, t.Value)
+            fmt.Printf("[%v] node %v SENT\n", m, t.Value)
             break out
         default:
             if !waiting {
-                fmt.Printf("[%v] node %v waiting", m, t.Value)
+                //fmt.Printf("[%v] node %v waiting", m, t.Value)
                 waiting = true
             } else {
-                fmt.Printf(wm)
+                //fmt.Printf(wm)
             }
         }
+        mu.Unlock()
     }
+    mu.Unlock()
 
     Walk(m, wm, t.Right, ch)
-    fmt.Printf("[%v] node %v Right DONE\n", m, t.Value)
+    //fmt.Printf("[%v] node %v Right done\n", m, t.Value)
 }
 
 func walkTree (m, wm string, t *tree.Tree, ch chan int) {
     Walk(m, wm, t, ch)
-    fmt.Printf("Finish\n")
+    //fmt.Printf("Finish\n")
+    wg.Done()
     close(ch)
 }
 
@@ -58,12 +67,14 @@ func Same(t1, t2 *tree.Tree) bool {
     ch1 := make(chan int)
     ch2 := make(chan int)
 
-    go walkTree("t1", ".", t1, ch1)
-    go walkTree("t2", "*", t2, ch2)
     fmt.Printf("Comparing..\n")
     fmt.Println(t1)
     fmt.Println(t2)
 
+    wg.Add(2)
+    go walkTree("t1", ".", t1, ch1)
+    go walkTree("t2", "*", t2, ch2)
+
     i := 0
     for ; i < 10; i++ {
         v1 := <- ch1
@@ -74,6 +85,8 @@ func Same(t1, t2 *tree.Tree) bool {
         }
     }
     fmt.Printf("Trees are identical\n")
+
+    wg.Wait()
     return true
 }
 
@@ -82,6 +95,7 @@ func main() {
     t1 := tree.New(1)
     fmt.Println(t1)
 
+    wg.Add(1)
     go walkTree("t1", ".", t1, ch)
     //var res bytes.Buffer
     var res strings.Builder
@@ -90,10 +104,12 @@ func main() {
         res.Write([]byte(strconv.Itoa(x)))
     }
     fmt.Printf("Result: %v\n", res.String())
+    wg.Wait()
 
     t2 := tree.New(1)
 
     b := Same(t1, t2)
     fmt.Println(b)
+    //time.Sleep(time.Second)
 }