<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sonu Kumar Saw</title>
    <description>The latest articles on DEV Community by Sonu Kumar Saw (@devsaw99).</description>
    <link>https://dev.to/devsaw99</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F819478%2Fd2ff7a56-5df4-495b-8f6f-93d3a6af7154.jpeg</url>
      <title>DEV Community: Sonu Kumar Saw</title>
      <link>https://dev.to/devsaw99</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devsaw99"/>
    <language>en</language>
    <item>
      <title>Mutex Lock in Golang</title>
      <dc:creator>Sonu Kumar Saw</dc:creator>
      <pubDate>Fri, 04 Mar 2022 15:00:14 +0000</pubDate>
      <link>https://dev.to/devsaw99/mutex-lock-in-golang-1le0</link>
      <guid>https://dev.to/devsaw99/mutex-lock-in-golang-1le0</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally posted at &lt;a href="https://ioscript.org/mutex-locks-in-golang" rel="noopener noreferrer"&gt;ioscript.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While writing concurrent code in Golang, often programs face situations when two or more goroutines try to access and modify shared variables. Such conditions can lead to inconsistency in data stored in the shared variable. Such conditions are called Race conditions. You can learn more about race conditions from our previous article of this course, &lt;a href="https://dev.to/devsaw99/race-condition-in-golang-52c1"&gt;Race conditions in Golang&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's see one example of Race Condition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

func main() {

    var counter int
    fmt.Println("Initial value: ", counter)

    // deploy 5 goroutines
    for i := 0; i &amp;lt; 5; i++ {

        wg.Add(1)

        go func() {
            defer wg.Done()
            //increment the counter 100 times
            for j := 0; j &amp;lt; 100; j++ {
                temp := counter
                time.Sleep(time.Microsecond * 1)
                temp += 1
                counter = temp
            }

        }()

    }

    wg.Wait()
    fmt.Println("Final value: ", counter)
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Initial value:  0
Final value:  102
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see in the output, there's definitely an inconsistency in our counter variable. The expected value of the counter is &lt;code&gt;500&lt;/code&gt; and we go the &lt;code&gt;102&lt;/code&gt;. Let's find out where is the issue in the above code causing the Race condition. To find the race condition in our code, we can use the command &lt;code&gt;go run -race main.go&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When we run/build our code with the &lt;code&gt;-race&lt;/code&gt; flag on. It generates the following output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Initial value:  0
==================
WARNING: DATA RACE
Read at 0x00c000126008 by goroutine 8:
  main.main.func1()
      ioScript/concurrency/main.go:25 +0xa8

Previous write at 0x00c000126008 by goroutine 7:
  main.main.func1()
      ioScript/concurrency/main.go:28 +0xce

Goroutine 8 (running) created at:
  main.main()
     ioScript/concurrency/main.go:21 +0xdb

Goroutine 7 (running) created at:
  main.main()
      ioScript/concurrency/main.go:21 +0xdb
==================
Final value:  101
Found 1 data race(s)
exit status 66
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see in the logs that go runtime found 1 data race. A race condition was found due to lines 25 and 28. There is a read operation in line 25 and a write operation at 28. Goroutine 8 is reading from the &lt;code&gt;counter&lt;/code&gt; variable and Goroutine 7 is trying to write to the counter variable. &lt;/p&gt;

&lt;p&gt;We can solve this race condition if we somehow restrict the read and write operation of the shared variable to one goroutine at a time. &lt;/p&gt;

&lt;h2&gt;
  
  
  sync.Mutex
&lt;/h2&gt;

&lt;p&gt;Mutex is a synchronization primitive which restricts one or more goroutine to enter the critical section while another goroutine is executing the critical section.&lt;/p&gt;

&lt;p&gt;When one goroutine is executing the critical section of the code, mutex locks the section. Other goroutines need to wait till the execution is complete and the lock is released by the first goroutine.&lt;/p&gt;

&lt;p&gt;Let's try to fix our above code using mutex lock.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

func main() {

    var counter int
    var mu sync.Mutex

    fmt.Println("Initial value: ", counter)

    // deploy 5 goroutines
    for i := 0; i &amp;lt; 5; i++ {

        wg.Add(1)

        go func() {
            defer wg.Done()
            //increment the counter 100 times
            for j := 0; j &amp;lt; 100; j++ {

                mu.Lock()
                temp := counter
                time.Sleep(time.Microsecond * 1)
                temp += 1
                counter = temp
                mu.Unlock()
            }

        }()

    }

    wg.Wait()
    fmt.Println("Final value: ", counter)
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ioscript@ioscript:concurrency$  go run -race main.go 
Initial value:  0
Final value:  500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, let's break down what we have done here. We have declared a variable name &lt;code&gt;mu&lt;/code&gt; which is of type &lt;strong&gt;Mutex&lt;/strong&gt; provided by the  &lt;strong&gt;sync&lt;/strong&gt; package of golang. &lt;strong&gt;Mutex&lt;/strong&gt; type provides two methods: Lock() and Unlock().&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lock( )&lt;/strong&gt;: As the name suggests, it locks the mutex. If the lock is already in use, other goroutine blocks until the mutex is available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unlock( )&lt;/strong&gt;: It unlocks the mutex. It throws a runtime error if the mutex is not locked when unlock was called.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our code above, we have used &lt;code&gt;mu.Lock()&lt;/code&gt; just before we are reading a value from the counter variable. Then we are incrementing the value and write the value to the counter variable again. Since read-write operations are complete, we are releasing the lock on mutex using &lt;code&gt;mu.Unlock( )&lt;/code&gt; so that other goroutines can acquire the lock again and execute the critical section. &lt;/p&gt;

&lt;p&gt;When we run this code with the &lt;code&gt;-race&lt;/code&gt; flag, we don't get any error message and the correct output is displayed in the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we had a quick look into Race conditions and how they can create data inconsistency in our program. We then learn about Mutex Locks and how we can use them to solve race conditions in our code and ensure that our program always returns expected results. &lt;/p&gt;

&lt;h2&gt;
  
  
  Before You Leave
&lt;/h2&gt;

&lt;p&gt;If you found this article valuable, you can support us by dropping a like and sharing this article with your friends. You can find more articles in this series &lt;a href="https://ioscript.org/series/go-concurrency" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can sign up for our newsletter to get notified whenever we post awesome content on Golang.&lt;/p&gt;

&lt;p&gt;You can also &lt;strong&gt;let us know what you would like to read next?&lt;/strong&gt; Drop a comment or email @ &lt;a href="mailto:sonukumarsaw@ioscript.org"&gt;sonukumarsaw@ioscript.org&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://go.dev/" rel="noopener noreferrer"&gt;Go docs&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://g.co/kgs/ye6b6C" rel="noopener noreferrer"&gt;Go in Action&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gobyexample.com/" rel="noopener noreferrer"&gt;GoByExample&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://g.co/kgs/8DKFH5" rel="noopener noreferrer"&gt;Concurrency in Go&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1645039088124%2Fj9q9kQHgH.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1645039088124%2Fj9q9kQHgH.png" alt="Frame 1.png"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>codenewbie</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Race Condition in Golang</title>
      <dc:creator>Sonu Kumar Saw</dc:creator>
      <pubDate>Sat, 26 Feb 2022 19:19:50 +0000</pubDate>
      <link>https://dev.to/devsaw99/race-condition-in-golang-52c1</link>
      <guid>https://dev.to/devsaw99/race-condition-in-golang-52c1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally posted at &lt;a href="https://ioscript.org/race-condition-in-golang"&gt;ioscript.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Writing a concurrent code is often a difficult task. often programmers working with concurrent code, face similar kinds of bugs. One of them is inconsistency while manipulating the data using concurrent goroutines.&lt;/p&gt;

&lt;p&gt;Let's see an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "sync"
)

var msg string
var wg sync.WaitGroup

func foo() {
    defer wg.Done()
    msg = "Hello Universe"
}

func bar() {
    defer wg.Done()
    msg = "Hello Cosmos"
}

func main() {

    msg = "Hello world"

    wg.Add(2)
    go foo()
    go bar()

    wg.Wait()
    fmt.Println(msg)

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: If you are not familiar with Goroutines and  WaitGroups, I recommend checking out our course on &lt;a href="https://ioscript.org/series/go-concurrency"&gt;Concurrency in Golang&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the above code example, we are deploying two goroutines named &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt;. Both goroutines are updating a variable named message to &lt;code&gt;"Hello Universe"&lt;/code&gt; and &lt;code&gt;"Hello Cosmos"&lt;/code&gt; accordingly. When we run this code, It will deploy the two goroutines. These goroutines eventually update the value of msg and join back to the &lt;code&gt;main&lt;/code&gt; goroutine. Since two goroutines are updating the same variable in the above code, we cannot determine the output of the &lt;code&gt;fmt.Println(msg)&lt;/code&gt;, i.e, It will either print &lt;code&gt;"Hello Universe"&lt;/code&gt; or &lt;code&gt;"Hello Cosmos"&lt;/code&gt;. Since we cannot determine the value stored in the &lt;code&gt;msg&lt;/code&gt; variable, this will be a serious bug in our code that can break our software.&lt;/p&gt;

&lt;p&gt;Let's see another example with a real-life scenario. Michael and his wife have a joint bank account, they use the same account to make purchases. One fine day, Michael went to have coffee at Starbucks 🥤🥤. Meanwhile, her wife went shopping and purchased a beautiful dress 👗👗 for herself. They paid their bills simultaneously, But the bank software was not implemented correctly which resulted in an inconsistency in their balance amount at the bank.&lt;/p&gt;

&lt;p&gt;Let's have a look at the bank software's code and see what went wrong.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "sync"
)

var bankBalance int
var wg sync.WaitGroup

func Purchase(purchaseAmount int) {
    defer wg.Done()

    value := bankBalance
    value = value - purchaseAmount
    bankBalance = value
}

func main() {

    //initially Michael and his wife had $1000 USD in their bank account
    bankBalance = 1000

    //they made bill payment simultaneously
    wg.Add(2)

    go Purchase(5)
    go Purchase(157)

    wg.Wait()

    //final amount in there bank account
    fmt.Println("Final amount : ", bankBalance)
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we run the above code, It can result in &lt;code&gt;995&lt;/code&gt;, &lt;code&gt;838&lt;/code&gt; or &lt;code&gt;843&lt;/code&gt;. Final values completely depend on the order of execution of the &lt;code&gt;Purchase&lt;/code&gt; goroutine. &lt;/p&gt;

&lt;p&gt;The above case is called Race condition in programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Race Condition
&lt;/h2&gt;

&lt;p&gt;A race condition occurs when two or more concurrent goroutines try to access and modify the same data. For example, if one goroutine tries to read a variable, meanwhile other goroutines are trying to update the value of the same variable.&lt;/p&gt;

&lt;p&gt;Race condition mostly occurs, if the developer thinks the concurrent program is executing sequentially. In the above example of bank software code, the developer might have assumed &lt;code&gt;go Purchase(5)&lt;/code&gt; will complete its execution first than &lt;code&gt;go Purchase(157)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to detect race conditions in GO ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go provides built-in support to tackle the Race condition issue. We can use the &lt;code&gt;-race&lt;/code&gt; flag while compiling or building our code to detect the race conditions in our program.&lt;/p&gt;

&lt;p&gt;Let's run our code above with the &lt;code&gt;-race&lt;/code&gt; flag to detect where the race condition is actually happening.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sonukumarsaw@legion-5PRO:concurrency$ go run -race main.go
==================
WARNING: DATA RACE
Read at 0x0000005d4400 by goroutine 7:
  main.Purchase()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:14 +0x74
  main.main·dwrap·2()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:27 +0x39

Previous write at 0x0000005d4400 by goroutine 8:
  main.Purchase()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:16 +0x8c
  main.main·dwrap·3()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:28 +0x39

Goroutine 7 (running) created at:
  main.main()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:27 +0x90

Goroutine 8 (finished) created at:
  main.main()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:28 +0xd2
==================
Final amount : 838
Found 1 data race(s)
exit status 66
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, there's a lot of things going on here. Let's go through it step by step. First of all, we &lt;strong&gt;Found 1 data race&lt;/strong&gt;. Now let's see the most important lines&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Goroutine 7 (running) created at:
  main.main()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:27 +0x90

Goroutine 8 (finished) created at:
  main.main()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:28 +0xd2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above two message shows, two goroutines are deployed named &lt;strong&gt;&lt;code&gt;Goroutine 7&lt;/code&gt;&lt;/strong&gt; at line 27, i.e, &lt;code&gt;go Purchase(5)&lt;/code&gt; and &lt;strong&gt;&lt;code&gt;Goroutine 8&lt;/code&gt;&lt;/strong&gt; at line 28, i.e, &lt;code&gt;go Purchase(157)&lt;/code&gt;. Also, &lt;code&gt;Goroutine 8&lt;/code&gt; has already completed its execution while &lt;code&gt;Goroutine 7&lt;/code&gt; is still running.&lt;/p&gt;

&lt;p&gt;Now let's see the next part.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read at 0x0000005d4400 by goroutine 7:
  main.Purchase()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:14 +0x74
  main.main·dwrap·2()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:27 +0x39

Previous write at 0x0000005d4400 by goroutine 8:
  main.Purchase()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:16 +0x8c
  main.main·dwrap·3()
      /home/sonukumarsaw/alpha/ioScript/concurrency/main.go:28 +0x39
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It clearly states that &lt;strong&gt;&lt;code&gt;Read at 0x0000005d4400 by goroutine 7:&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;Previous write at 0x0000005d4400 by goroutine 8:&lt;/code&gt;&lt;/strong&gt;. This means Goroutine 7 is trying to read the same memory address &lt;code&gt;0x0000005d4400&lt;/code&gt; which was earlier written by Goroutine 8. &lt;/p&gt;

&lt;p&gt;Even though, we could detect the race condition and its cause. We can still see the correct amount in the output i.e, &lt;code&gt;Final amount : 838&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Let's make some changes in our code to make sure, our code returns the incorrect amount.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "sync"
)

var bankBalance int
var wg sync.WaitGroup

func Purchase(purchaseAmount int) {
    defer wg.Done()

    value := bankBalance
    time.Sleep(1 * time.Second)                 // some delay in processing the calculation
    value = value - purchaseAmount
    bankBalance = value
}


func main() {

    //initially Michael and his wife had $1000 USD in their bank account
    bankBalance = 1000

    //they made bill payment simultaneously
    wg.Add(2)

    go Purchase(5)
    go Purchase(157)

    wg.Wait()

    //final amount in there bank account
    fmt.Println("Final amount : ", bankBalance)
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have added &lt;code&gt;time.Sleep()&lt;/code&gt; to imitate a processing delay. Now when we run this program, we will never get the correct amount in the output. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to fix the race condition ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To avoid race conditions in our program, any operation in a shared variable, must be executed atomically&lt;/strong&gt;. Shared variables are those variables that are shared among the goroutines.&lt;/p&gt;

&lt;p&gt;We can execute a program atomically by locking the critical section, a section of the code where shared variables are being manipulated. Once, the execution of the critical section is completed by one goroutine, other goroutines can acquire the lock and complete its execution as well.&lt;/p&gt;

&lt;p&gt;We can use go's built-in &lt;code&gt;Mutex&lt;/code&gt; lock. Mutex lock is a part of the &lt;code&gt;sync&lt;/code&gt; package. We will see how to fix our code using Mutex lock in our next article. &lt;/p&gt;

&lt;h2&gt;
  
  
  Before You Leave
&lt;/h2&gt;

&lt;p&gt;If you found this article valuable, you can support us by dropping a like and sharing this article with your friends.&lt;/p&gt;

&lt;p&gt;You can sign up for our newsletter to get notified whenever we post awesome content on Golang.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://go.dev/"&gt;Go docs&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://g.co/kgs/ye6b6C"&gt;Go in Action&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gobyexample.com/"&gt;GoByExample&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://g.co/kgs/8DKFH5"&gt;Concurrency in Go&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iraIEHUn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645039088124/j9q9kQHgH.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iraIEHUn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645039088124/j9q9kQHgH.png" alt="Frame 1.png" width="880" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>codenewbie</category>
      <category>beginners</category>
      <category>opensource</category>
    </item>
    <item>
      <title>WaitGroups in Golang</title>
      <dc:creator>Sonu Kumar Saw</dc:creator>
      <pubDate>Tue, 22 Feb 2022 08:17:59 +0000</pubDate>
      <link>https://dev.to/devsaw99/waitgroups-in-golang-1jcn</link>
      <guid>https://dev.to/devsaw99/waitgroups-in-golang-1jcn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally posted at &lt;a href="https://ioscript.org/waitgroups-in-golang"&gt;ioscript.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the previous article, &lt;a href="https://ioscript.org/introduction-to-concurrency-in-golang"&gt;Introduction to Concurrency in Golang&lt;/a&gt;, of the series,&lt;a href="https://ioscript.org/series/go-concurrency"&gt;Concurrency in Golang&lt;/a&gt;, we came across a problem where one or more goroutines might not necessarily finish execution before the main goroutine does, thus we were unable to see the message printed by the unfinished goroutine. We fixed the issue by adding &lt;code&gt;time.Sleep()&lt;/code&gt; in the main goroutine to put it to sleep for a few seconds and thus increasing the probability of other goroutines finishing before the main does. Although our code worked in that particular case, most certainly it will not work for all cases. In this article, we will see, how we can make use of the **WaitGroup **synchronization primitive provided by Go. &lt;/p&gt;

&lt;p&gt;Before we discuss &lt;strong&gt;WaitGroups&lt;/strong&gt; let's have a look into Go's concurrency model &lt;em&gt;fork-join&lt;/em&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Fork-Join Model
&lt;/h2&gt;

&lt;p&gt;In concurrency, Fork-Join Model is a way of setting up and executing concurrent programs, such that execution branches off in designated points and joins or merges at a subsequent point and resumes the sequential execution. The word &lt;strong&gt;Fork&lt;/strong&gt; refers to any point of time in the program runtime, it can create one or more &lt;em&gt;child&lt;/em&gt; branches of execution to be run either concurrently or in some cases parallel to the &lt;em&gt;parent&lt;/em&gt;. The word &lt;strong&gt;Join&lt;/strong&gt; refers to the point in the future when concurrent execution branches&lt;br&gt;
join back to the parent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oiB_6ix3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645123256809/2nuzK8fhN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oiB_6ix3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645123256809/2nuzK8fhN.png" alt="Frame 2.png" width="880" height="806"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  WaitGroups
&lt;/h2&gt;

&lt;p&gt;Now, that we know more about the concurrency model, Fork-Join. Let's go through our code from the last article and try to fix it without putting the main goroutine to sleep.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import "fmt"

func sayGreetings() {
    fmt.Println("Hello World!!")
}

func main() {
    go sayGreetings()
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we run the above code, there will be two possibilities. First, the &lt;strong&gt;sayGreetings&lt;/strong&gt; goroutine prints &lt;code&gt;Hello World!&lt;/code&gt; and complete its execution before the &lt;strong&gt;main&lt;/strong&gt; goroutine does. In that case, both Fork and Join operations will happen. In the second case,  the &lt;strong&gt;sayGreetings&lt;/strong&gt; goroutine won't be able to complete its execution before the *&lt;em&gt;main *&lt;/em&gt; goroutine does. In such a case, the Join operation will not happen. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MJuV13Tj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645124232995/ZEZ2rgNG2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MJuV13Tj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645124232995/ZEZ2rgNG2.png" alt="Frame 2 (1).png" width="880" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To solve the above issue, we need to make sure that the &lt;strong&gt;Join&lt;/strong&gt; operation happens in all the cases before the main goroutine completes its execution. We can use synchronization primitive &lt;strong&gt;WaitGroup&lt;/strong&gt; provided by the &lt;strong&gt;sync&lt;/strong&gt; package of Go's inbuilt library.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;WaitGroup **waits for a collection of goroutines to finish. We can think of **WaitGroup&lt;/strong&gt; as a concurrent-safe counter. WaitGroup provides three methods attached to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    type WaitGroup

        func (wg *WaitGroup) Add(delta int)
        func (wg *WaitGroup) Done()
        func (wg *WaitGroup) Wait()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;func (wg *WaitGroup) Add(delta int)&lt;/code&gt;&lt;/strong&gt; method increments the counter by the integer passed in. Integer passed into the Add method means the number of new goroutines created. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;func (wg *WaitGroup) Done()&lt;/code&gt;&lt;/strong&gt; method decrements the counter by one. We call the Done method when a goroutine completes its execution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;func (wg *WaitGroup) Wait()&lt;/code&gt;&lt;/strong&gt; method is used to block the execution until all the goroutines deployed have already completed their execution.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see how to use &lt;strong&gt;WaitGroups&lt;/strong&gt; in our previous code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
package main

import (
    "fmt"
    "sync"
)

var wg sync.WaitGroup    // 1

func sayGreetings() {

    defer wg.Done()      // 3

    fmt.Println("Hello World!!")

}

func main() {

    wg.Add(1)           // 2  
    go sayGreetings()

    wg.Wait()           // 4
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above example will deterministically block the main goroutine until the sayGreetings goroutine completes its execution &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We created a global variable type WaitGroup from the sync package using &lt;code&gt;var wg sync.WaitGroup&lt;/code&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;code&gt;main&lt;/code&gt; function we call &lt;code&gt;wg.Add(1)&lt;/code&gt; just before we started a goroutine &lt;code&gt;sayGreetings&lt;/code&gt;. This indicates that we have launched one goroutine &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Here we call &lt;code&gt;wg.Done()&lt;/code&gt; using defer keyword to make sure that &lt;code&gt;wg.Done()&lt;/code&gt; is called just before we exit the sayGreetings goroutine closure. This indicates we have completed the execution of one goroutine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Here we call &lt;code&gt;wg.Wait()&lt;/code&gt;, which will block further execution of the &lt;code&gt;main&lt;/code&gt; goroutine until all the goroutines have completed execution.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's see another example on WaitGroups where we launch multiple goroutines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "sync"
)

var wg sync.WaitGroup

func sayGreetings(i int) {

    defer wg.Done()

    fmt.Printf("Hello from goroutine %v!!\n", i)

}

func main() {

    fmt.Println("Hello from the main goroutine !!")

    for i := 0; i &amp;lt; 5; i++ {

        wg.Add(1)
        go sayGreetings(i)

    }

    wg.Wait()

    fmt.Println("Bye!")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello from the main goroutine !!
Hello from goroutine 4!!
Hello from goroutine 0!!
Hello from goroutine 1!!
Hello from goroutine 2!!
Hello from goroutine 3!!
Bye !!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have modified the sayGreetings function to accept an integer value, in order to print the message. Also, we have made certain changes in the &lt;code&gt;main&lt;/code&gt; function to use a &lt;code&gt;for&lt;/code&gt; loop to deploy 5 goroutines to print the message. &lt;/p&gt;

&lt;p&gt;It's a good practice to call Add() as closely as possible to the goroutine its tracking. I have called wg.Add(1) just before deploying the goroutine. But you will also find some codes in which wg.Add() is called just before the &lt;code&gt;for&lt;/code&gt; loop, as shown in the below example. Both ways are correct. we just need to make sure that we use the correct integer value for the Add().&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
    const greetingsCount = 5

    wg.Add(greetingsCount)

    for i:=0; i&amp;lt;greetingsCount; i++ {

        go sayGreetings(i)

    }

    wg.Wait()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we learned about Go's concurrency model, WaitGroups, and the methods provided with it. We saw how we can use waitgroups to create a join point in our code and make sure all the goroutines deployed get executed completely before the main goroutine exits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before You Leave
&lt;/h2&gt;

&lt;p&gt;If you found this article valuable, you can support us by dropping a like and sharing this article with your friends. &lt;/p&gt;

&lt;p&gt;You can sign up for our newsletter to get notified whenever we post awesome content on Golang.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://go.dev/"&gt;Go docs&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://g.co/kgs/ye6b6C"&gt;Go in Action&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gobyexample.com/"&gt;GoByExample&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://g.co/kgs/8DKFH5"&gt;Concurrency in Go&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check our ioscript.org for more such contents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iraIEHUn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645039088124/j9q9kQHgH.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iraIEHUn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645039088124/j9q9kQHgH.png" alt="Frame 1.png" width="880" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>codenewbie</category>
      <category>concurrency</category>
      <category>waitgroups</category>
    </item>
    <item>
      <title>Introduction to Concurrency in Golang</title>
      <dc:creator>Sonu Kumar Saw</dc:creator>
      <pubDate>Tue, 22 Feb 2022 08:11:38 +0000</pubDate>
      <link>https://dev.to/devsaw99/introduction-to-concurrency-in-golang-h1n</link>
      <guid>https://dev.to/devsaw99/introduction-to-concurrency-in-golang-h1n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally posted at &lt;a href="https://ioscript.org/introduction-to-concurrency-in-golang"&gt;ioscript.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In computer science, often we write programs written as a linear path of code, for example, a program to read a JSON file or a program to calculate your bill. This type of program to one task at a time and follow a linear path to perform that task and finish. But sometimes we need to write a program that needs to execute multiple paths, in such conditions we use concurrent programming. For example, A web service has to connect multiple requests, process the data, and then respond to the requests. Since web services are built to handle concurrent requests, we don't have to wait for one request to complete and return the response in order to send another request to the web service. &lt;/p&gt;

&lt;h2&gt;
  
  
  Concurrency vs Parallelism
&lt;/h2&gt;

&lt;p&gt;Programmers generally get confused by the word Concurrency with Parallelism, both the topics are related but not the same. &lt;em&gt;Concurrency&lt;/em&gt; is the composition of independently executing processes, while &lt;em&gt;Parallelism&lt;/em&gt; is the simultaneous execution of the programs. &lt;/p&gt;

&lt;p&gt;Below diagram shows how &lt;em&gt;Concurrency&lt;/em&gt; is different from &lt;em&gt;Parallelism&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7QOZFjSZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644682610589/agzY2lf7E.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7QOZFjSZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644682610589/agzY2lf7E.png" alt="Group 3 (7).png" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The flow diagram on the left shows, the same processor is being used to complete two different tasks concurrently. The flow diagram on the right shows two processes being executed parallelly in two different processors.&lt;/em&gt;&lt;br&gt;
You can learn more about this from the &lt;a href="https://youtu.be/oV9rvDllKEg"&gt;workshop&lt;/a&gt; by &lt;strong&gt;Rob Pike&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Concurrency in Go
&lt;/h2&gt;

&lt;p&gt;Concurrency in Go has been built directly into Go's runtime. Also, Go has a built-in library which makes writing and maintaining concurrent go programs easier as compared to the other programming languages.&lt;/p&gt;
&lt;h3&gt;
  
  
  Goroutines
&lt;/h3&gt;

&lt;p&gt;Concurrency in Go is powered by &lt;strong&gt;goroutines&lt;/strong&gt;. Goroutines aren't OS threads, they are higher levels of abstraction known as coroutines. They are managed by the Go's runtime. Every Go program has at least one goroutine by default, which is created by the &lt;code&gt;main&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;To create a goroutine we use the keyword &lt;code&gt;go&lt;/code&gt; in front of any function. Here's a simple example of a goroutine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import "fmt"

func sayGreetings() {
    fmt.Println("Hello World!!")
}

func main() {
    go sayGreetings()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, let's discuss what is happening in the code shared above. We have created a function names &lt;code&gt;sayGreetings&lt;/code&gt;, which will be printing a message "Hello World". We have another function, &lt;code&gt;main&lt;/code&gt;, which is calling the &lt;code&gt;sayGreetings&lt;/code&gt; function as a goroutine.  When we run this program, It will create two goroutines. The first one would be the main goroutine, and another one would be the goroutine created by &lt;code&gt;sayGreetings&lt;/code&gt; function. &lt;/p&gt;

&lt;p&gt;This program will compile successfully, however, there is a problem with this example: it's undetermined whether &lt;code&gt;Hello World!!&lt;/code&gt; will be printed on the console or not. The goroutine for &lt;code&gt;sayGreetings&lt;/code&gt; will be created, but, we can't determine if it will be executed by the time main goroutine executes completed and exits.&lt;/p&gt;

&lt;p&gt;So, In order to solve above issue, we have to make sure that &lt;code&gt;sayGreetings&lt;/code&gt; goroutine get executed before &lt;code&gt;main&lt;/code&gt; goroutine completes its execution. We can make use of time package and put our &lt;code&gt;main&lt;/code&gt; goroutine on sleep for &lt;code&gt;2 secs&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import "fmt"

func sayGreetings() {
    fmt.Println("Hello World!!")
}

func main() {
    go sayGreetings()
    time.Sleep(2 * time.Second)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we run above program, we will get the expected output i.e, &lt;code&gt;Hello World!!&lt;/code&gt; in the console.&lt;/p&gt;

&lt;p&gt;Even though we were able to print &lt;code&gt;Hello World!!&lt;/code&gt; in the console, above code is not correct. By adding &lt;code&gt;time.Sleep()&lt;/code&gt; we are just increasing the probability of &lt;code&gt;main&lt;/code&gt; goroutine not completing its execution before &lt;code&gt;sayGreetings&lt;/code&gt;. If we add another goroutine in our program which takes more than 2 seconds to complete its execution, then again we will get into same issue as before. To make sure that our code works deterministically we need to use Go's synchronization primitives such as &lt;strong&gt;Mutex lock&lt;/strong&gt;s, &lt;strong&gt;waitgroups&lt;/strong&gt;, &lt;strong&gt;channels&lt;/strong&gt;, etc.&lt;/p&gt;

&lt;p&gt;We will explore more about &lt;strong&gt;Go's synchronization primitives&lt;/strong&gt; in our next part of this series.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before You Leave
&lt;/h2&gt;

&lt;p&gt;If you found this article valuable, you can support us by dropping a like and sharing this article with your friends. &lt;/p&gt;

&lt;p&gt;You can sign up for our newsletter to get notified whenever we post awesome contents on Golang.&lt;/p&gt;

&lt;p&gt;Check our &lt;a href="https://ioscript.org"&gt;ioscript.org&lt;/a&gt; for more such contents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iraIEHUn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645039088124/j9q9kQHgH.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iraIEHUn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1645039088124/j9q9kQHgH.png" alt="Frame 1.png" width="880" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>codenewbie</category>
      <category>concurrency</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
