<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Channels on avni.sh</title>
    <link>http://www.avni.sh/tags/channels/</link>
    <description>Recent content in Channels on avni.sh</description>
    <image>
      <title>avni.sh</title>
      <url>http://www.avni.sh/cover.webp</url>
      <link>http://www.avni.sh/cover.webp</link>
    </image>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Tue, 12 Sep 2023 00:00:00 +0000</lastBuildDate>
    <atom:link href="http://www.avni.sh/tags/channels/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Concurrency in Go</title>
      <link>http://www.avni.sh/posts/go/concurrency-in-go/</link>
      <pubDate>Tue, 12 Sep 2023 00:00:00 +0000</pubDate>
      <guid>http://www.avni.sh/posts/go/concurrency-in-go/</guid>
      <description>Implementing concurrent programs in Go using goroutines, channels, and WaitGroups</description>
      <content:encoded><![CDATA[<p>We can make a program concurrent if we can split it as multiple independent tasks executed at the same time.</p>
<p>In concurrency, we execute different portions of a program at the same time (on single or multiple CPU threads) whereas in parallelism a singular task (or subtasks) is executed parallelly on multiple CPU threads.</p>
<blockquote>
<p>Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once.</p>
<p><cite><a href="https://youtu.be/oV9rvDllKEg" target=_blank>Rob Pike</a>, Co-Creator of Go</cite></p></blockquote>
<h1 id="goroutines">Goroutines</h1>
<p>By adding the <code>go</code> keyword before a statement we can start a new <strong>goroutine</strong>. It will create a lightweight execution thread to execute the statement concurrently with the succeeding tasks in its parent function.</p>
<p>The program will end once the <code>main</code> goroutine is finished irrespective of the current state of other goroutines.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Go" data-lang="Go"><span class="line"><span class="cl"><span class="c1">// Example of a non-concurrent program</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="s">&#34;time&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">testFunc</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="nx">j</span><span class="o">:=</span><span class="mi">0</span><span class="p">;</span><span class="nx">j</span><span class="p">&lt;</span><span class="mi">3</span><span class="p">;</span><span class="nx">j</span><span class="o">++</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Hello from testfunc&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">testFunc</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="nx">i</span><span class="o">:=</span><span class="mi">0</span><span class="p">;</span><span class="nx">i</span><span class="p">&lt;</span><span class="mi">3</span><span class="p">;</span><span class="nx">i</span><span class="o">++</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Hello from main&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from testfunc</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from testfunc</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from testfunc</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from main</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from main</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from main</span>
</span></span></code></pre></div><p>The output of this program will be three statements from <code>testFunc()</code> functions followed by three statements from the <code>main()</code> function.</p>
<p>But, if we add the <code>go</code> keyword before <code>testFunc()</code>, we can create a new <em>goroutine</em> that will execute the <code>testFunc()</code> function concurrently with the statements in <code>main()</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="s">&#34;time&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">testFunc</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="nx">j</span><span class="o">:=</span><span class="mi">0</span><span class="p">;</span><span class="nx">j</span><span class="p">&lt;</span><span class="mi">3</span><span class="p">;</span><span class="nx">j</span><span class="o">++</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Hello from testfunc&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">go</span> <span class="nf">testFunc</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="nx">i</span><span class="o">:=</span><span class="mi">0</span><span class="p">;</span><span class="nx">i</span><span class="p">&lt;</span><span class="mi">3</span><span class="p">;</span><span class="nx">i</span><span class="o">++</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Hello from main&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from main</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from testfunc</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from testfunc</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from testfunc</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from main</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Hello from main</span>
</span></span></code></pre></div><h1 id="channels">Channels</h1>
<p>To send and receive values between Goroutines we have <strong>channels</strong>.</p>
<p>Channels are declared using the <code>make(chan &lt;datatype&gt;)</code> function with the datatype of the transmitted value, for example, <code>make(chan string)</code> will create a channel that could be used to send and receive <code>string</code> values.</p>
<p><code>chan&lt;- string</code> denotes a send-only channel and <code>&lt;-chan string</code> denotes a receive-only channel for string values.</p>
<p>To iterate over the values received on a channel we can define a <code>for</code> loop with <code>range</code> like in the program below.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Go" data-lang="Go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="s">&#34;time&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="s">&#34;math/rand&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Sends random integer on randomVal channel every 2 seconds</span>
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">getRandomValue</span><span class="p">(</span><span class="nx">randomVal</span> <span class="kd">chan</span><span class="o">&lt;-</span> <span class="kt">int</span><span class="p">,</span> <span class="nx">numValues</span> <span class="kt">int</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="nx">i</span><span class="o">:=</span><span class="mi">0</span><span class="p">;</span><span class="nx">i</span><span class="p">&lt;</span><span class="nx">numValues</span><span class="p">;</span><span class="nx">i</span><span class="o">++</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nx">value</span> <span class="o">:=</span> <span class="nx">rand</span><span class="p">.</span><span class="nf">Int</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">                <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;getRandomValue(): Sent Random Integer&#34;</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="c1">// Send a value to randomVal channel</span>
</span></span><span class="line"><span class="cl">                <span class="nx">randomVal</span> <span class="o">&lt;-</span> <span class="nx">value</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="c1">// 2 seconds interval to ensure that the receiver gets enough time</span>
</span></span><span class="line"><span class="cl">                <span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="o">*</span><span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="nb">close</span><span class="p">(</span><span class="nx">randomVal</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Listens to channel randomVal and prints received values on the terminal</span>
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">receiveRandomValue</span><span class="p">(</span><span class="nx">randomVal</span> <span class="o">&lt;-</span><span class="kd">chan</span> <span class="kt">int</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1">// Loops over values received in channel</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="nx">value</span> <span class="o">:=</span> <span class="k">range</span> <span class="nx">randomVal</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;recieveRandomValue(): Received Random Integer&#34;</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">randomValueChannel</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">int</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">go</span> <span class="nf">getRandomValue</span><span class="p">(</span><span class="nx">randomValueChannel</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">go</span> <span class="nf">receiveRandomValue</span><span class="p">(</span><span class="nx">randomValueChannel</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1">// To ensure that the main goroutine doesn&#39;t end </span>
</span></span><span class="line"><span class="cl">        <span class="c1">// before the other two goroutines</span>
</span></span><span class="line"><span class="cl">        <span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="o">*</span><span class="mi">10</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// getRandomValue(): Sent Random Integer 7680245871766720879</span>
</span></span><span class="line"><span class="cl"><span class="c1">// recieveRandomValue(): Received Random Integer 7680245871766720879</span>
</span></span><span class="line"><span class="cl"><span class="c1">// getRandomValue(): Sent Random Integer 1813843778283051521</span>
</span></span><span class="line"><span class="cl"><span class="c1">// recieveRandomValue(): Received Random Integer 1813843778283051521</span>
</span></span><span class="line"><span class="cl"><span class="c1">// getRandomValue(): Sent Random Integer 3359384099851901129</span>
</span></span><span class="line"><span class="cl"><span class="c1">// recieveRandomValue(): Received Random Integer 3359384099851901129</span>
</span></span><span class="line"><span class="cl"><span class="c1">// getRandomValue(): Sent Random Integer 3707965584748576540</span>
</span></span><span class="line"><span class="cl"><span class="c1">// recieveRandomValue(): Received Random Integer 3707965584748576540</span>
</span></span><span class="line"><span class="cl"><span class="c1">// getRandomValue(): Sent Random Integer 282243786570954167</span>
</span></span><span class="line"><span class="cl"><span class="c1">// recieveRandomValue(): Received Random Integer 282243786570954167</span>
</span></span></code></pre></div><p>A Go program finishes execution whenever the main goroutine is completed ignoring the current progress of other goroutines. To prevent this we can use a channel to flag completion of a goroutine.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Go" data-lang="Go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;math/rand&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;time&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">getRandomInt</span><span class="p">(</span><span class="nx">doneFlag</span> <span class="kd">chan</span> <span class="kt">bool</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Goroutine for getRandomInt() started&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Some random integer: &#34;</span><span class="p">,</span> <span class="nx">rand</span><span class="p">.</span><span class="nf">Int</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">	<span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="o">*</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c1">// Will send value to the channel</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// once the function is finished</span>
</span></span><span class="line"><span class="cl">	<span class="nx">doneFlag</span><span class="o">&lt;-</span><span class="kc">true</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">	<span class="nx">done</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">bool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">go</span> <span class="nf">getRandomInt</span><span class="p">(</span><span class="nx">done</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c1">// Main Goroutine will wait to receive a value on this channel</span>
</span></span><span class="line"><span class="cl">	<span class="o">&lt;-</span><span class="nx">done</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Main Goroutine has ended&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Goroutine for getRandomInt() started</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Some random integer:  4571662314887367842</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Main Goroutine has ended</span>
</span></span></code></pre></div><p>If we ran this program without <code>&lt;-done</code> the main goroutine would&rsquo;ve ended the program preemptively and its output would be</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Bash" data-lang="Bash"><span class="line"><span class="cl">Main Goroutine has ended
</span></span></code></pre></div><h2 id="buffering">Buffering</h2>
<p>A channel won&rsquo;t send values unless there is another channel ready to receive those values. But <strong>Buffered Channels</strong> allow a certain amount of values to be sent without a corresponding receiver for those values.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Go" data-lang="Go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nx">exampleBufferedChan</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">string</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c1">// Sending values to the buffered channel</span>
</span></span><span class="line"><span class="cl">	<span class="nx">exampleBufferedChan</span><span class="o">&lt;-</span><span class="s">&#34;c&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="nx">exampleBufferedChan</span><span class="o">&lt;-</span><span class="s">&#34;b&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="nx">exampleBufferedChan</span><span class="o">&lt;-</span><span class="s">&#34;a&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c1">// Receiving values from the buffered channel</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Value 1 from exampleBufferedChan:&#34;</span><span class="p">,</span><span class="o">&lt;-</span><span class="nx">exampleBufferedChan</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Value 2 from exampleBufferedChan:&#34;</span><span class="p">,</span><span class="o">&lt;-</span><span class="nx">exampleBufferedChan</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Value 3 from exampleBufferedChan:&#34;</span><span class="p">,</span><span class="o">&lt;-</span><span class="nx">exampleBufferedChan</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Value 1 from exampleBufferedChan: c</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Value 2 from exampleBufferedChan: b</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Value 3 from exampleBufferedChan: a</span>
</span></span></code></pre></div><p>The values from the channel will be received in the same order as they were sent.</p>
<h1 id="select">Select</h1>
<p>The <code>select</code> keyword is used to wait for values on multiple channels simultaneously. Its syntax is similar to a <a href="/posts/go/go-programming-language/#switch-cases" target="_blank"><code>switch</code></a>.</p>
<p><code>select</code> executes the first channel to receive value in <code>case</code> statements. If multiple channels are ready with values then one of them is selected at random.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Go" data-lang="Go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;time&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;math/rand&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">randomValueGenerator</span><span class="p">(</span><span class="nx">randomValueChannel</span> <span class="kd">chan</span><span class="o">&lt;-</span> <span class="kt">int</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">	<span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="o">*</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">randomValueChannel</span> <span class="o">&lt;-</span> <span class="nx">rand</span><span class="p">.</span><span class="nf">Int</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">	<span class="nx">channel1</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">int</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">channel2</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">int</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">go</span> <span class="nf">randomValueGenerator</span><span class="p">(</span><span class="nx">channel1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nf">randomValueGenerator</span><span class="p">(</span><span class="nx">channel2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c1">// Wait on channel1 and channel2 to receive values	</span>
</span></span><span class="line"><span class="cl">	<span class="k">select</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">case</span> <span class="nx">message1</span> <span class="o">:=</span> <span class="o">&lt;-</span> <span class="nx">channel1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">			<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Received value in channel1:&#34;</span><span class="p">,</span> <span class="nx">message1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="k">case</span> <span class="nx">message2</span> <span class="o">:=</span> <span class="o">&lt;-</span> <span class="nx">channel2</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">			<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Received value in channel2:&#34;</span><span class="p">,</span> <span class="nx">message2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Received value in channel2: 1923060859381349025</span>
</span></span></code></pre></div><p>I recommend executing this program multiple times as <code>channel1</code> and <code>channel2</code> will receive values at the same time and the output will be chosen at random by <code>select</code>.</p>
<h2 id="timeouts-using-timeafter">Timeouts using <code>time.After()</code></h2>
<p>The <code>time.After()</code> function returns a value after the time specified in its parameter. It could be used as a timeout <code>case</code> in <code>select</code> statements.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Go" data-lang="Go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;time&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">sendOnChannel</span><span class="p">(</span><span class="nx">doneFlag</span> <span class="kd">chan</span><span class="o">&lt;-</span> <span class="kt">bool</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// It will take at least 5 seconds for this function to finish</span>
</span></span><span class="line"><span class="cl">	<span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="o">*</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">doneFlag</span><span class="o">&lt;-</span><span class="kc">true</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">	<span class="nx">channel1</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">bool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">channel2</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">bool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">go</span> <span class="nf">sendOnChannel</span><span class="p">(</span><span class="nx">channel1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">go</span> <span class="nf">sendOnChannel</span><span class="p">(</span><span class="nx">channel2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">select</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">case</span> <span class="o">&lt;-</span><span class="nx">channel1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Channel 1 has responded&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">case</span> <span class="o">&lt;-</span><span class="nx">channel2</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Channel 2 has responded&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c1">// Added a 2 seconds timeout in the select statement</span>
</span></span><span class="line"><span class="cl">	<span class="k">case</span> <span class="o">&lt;-</span><span class="nx">time</span><span class="p">.</span><span class="nf">After</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="o">*</span><span class="mi">2</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;You&#39;ve hit a timeout&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// You&#39;ve hit a timeout</span>
</span></span></code></pre></div><h1 id="non-blocking-channel-operations-with-default">Non-Blocking Channel Operations with <code>default</code></h1>
<p>A <code>default</code> statement is defined in <code>select</code> to avoid blocking from unbuffered channels.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Go" data-lang="Go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">	<span class="nx">channel1</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">bool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">select</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">case</span> <span class="o">&lt;-</span><span class="nx">channel1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Something received on channel1&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c1">// Since there is no value received on channel1</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// the default case will be executed</span>
</span></span><span class="line"><span class="cl">	<span class="k">default</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;This is default statement&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;No value was received on channel1&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// This is default statement</span>
</span></span><span class="line"><span class="cl"><span class="c1">// No value was received on channel1</span>
</span></span></code></pre></div><h1 id="closing-channels">Closing Channels</h1>
<p>We can <code>close()</code> a channel to stop it from accepting further values.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Go" data-lang="Go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="nx">valueChannel</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">int</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">go</span> <span class="kd">func</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">		<span class="k">for</span> <span class="nx">i</span><span class="o">:=</span><span class="mi">0</span><span class="p">;</span><span class="nx">i</span><span class="p">&lt;</span><span class="mi">5</span><span class="p">;</span><span class="nx">i</span><span class="o">++</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">			<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Sending&#34;</span><span class="p">,</span><span class="nx">i</span><span class="p">,</span><span class="s">&#34;to channel valueChannel&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">			<span class="nx">valueChannel</span> <span class="o">&lt;-</span> <span class="nx">i</span>
</span></span><span class="line"><span class="cl">		<span class="p">}</span>
</span></span><span class="line"><span class="cl">		
</span></span><span class="line"><span class="cl">		<span class="c1">// Closing valueChannel to stop it from receiving further values</span>
</span></span><span class="line"><span class="cl">		<span class="nb">close</span><span class="p">(</span><span class="nx">valueChannel</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">}()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">go</span> <span class="kd">func</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">		<span class="k">for</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">			<span class="nx">value</span><span class="p">,</span> <span class="nx">openFlag</span> <span class="o">:=</span> <span class="o">&lt;-</span> <span class="nx">valueChannel</span>
</span></span><span class="line"><span class="cl">			<span class="k">if</span> <span class="p">!</span><span class="nx">openFlag</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">				<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;valueChannel is closed&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">				<span class="k">break</span>
</span></span><span class="line"><span class="cl">			<span class="p">}</span>
</span></span><span class="line"><span class="cl">			<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Received value:&#34;</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="p">}()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="o">&lt;-</span><span class="nx">valueChannel</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;All values received&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Main Goroutine finished&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Sending 0 to channel valueChannel</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Sending 1 to channel valueChannel</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Sending 2 to channel valueChannel</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Received value: 1</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Received value: 2</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Sending 3 to channel valueChannel</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Sending 4 to channel valueChannel</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Received value: 3</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Received value: 4</span>
</span></span><span class="line"><span class="cl"><span class="c1">// valueChannel is closed</span>
</span></span><span class="line"><span class="cl"><span class="c1">// All values received</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Main Goroutine finished</span>
</span></span></code></pre></div><h1 id="waitgroups">WaitGroups</h1>
<p>By default a Go program is finished when the <code>main</code> Goroutine is completed, We can add statements that wait for receiving over a channel like <code>&lt;-done</code> once all goroutines are finished.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Go" data-lang="Go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;math/rand&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;time&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">fastRoutine</span><span class="p">(</span><span class="nx">done</span> <span class="kd">chan</span> <span class="kt">bool</span><span class="p">)(</span><span class="kt">int</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// It will take at least 2 seconds to execute this function</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Fast Routine started&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="o">*</span><span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">done</span> <span class="o">&lt;-</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="nx">rand</span><span class="p">.</span><span class="nf">Int</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">slowRoutine</span><span class="p">(</span><span class="nx">done</span> <span class="kd">chan</span> <span class="kt">bool</span><span class="p">)(</span><span class="kt">int</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// It will take at least 5 seconds to execute this function</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Slow Routine started&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="o">*</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">done</span> <span class="o">&lt;-</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="nx">rand</span><span class="p">.</span><span class="nf">Int</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">	<span class="nx">done</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">bool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">done2</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">bool</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">go</span> <span class="kd">func</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fastRandomVal</span> <span class="o">:=</span> <span class="nf">fastRoutine</span><span class="p">(</span><span class="nx">done</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Value received from fast routine:&#34;</span><span class="p">,</span> <span class="nx">fastRandomVal</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">}()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">go</span> <span class="kd">func</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">		<span class="nx">slowRandomVal</span> <span class="o">:=</span> <span class="nf">slowRoutine</span><span class="p">(</span><span class="nx">done2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Value received from slow routine:&#34;</span><span class="p">,</span> <span class="nx">slowRandomVal</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">}()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="o">&lt;-</span><span class="nx">done</span>
</span></span><span class="line"><span class="cl">	<span class="o">&lt;-</span><span class="nx">done2</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Slow Routine started</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Fast Routine started</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Value received from fast routine: 1556543771289280615</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Value received from slow routine: 2312691093026658070</span>
</span></span></code></pre></div><p>But <code>sync.WaitGroup</code> provides a much more elegant way to monitor multiple Goroutines at once.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Go" data-lang="Go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;fmt&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;sync&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;math/rand&#34;</span>
</span></span><span class="line"><span class="cl">	<span class="s">&#34;time&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">fastRoutine</span><span class="p">()(</span><span class="kt">int</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Fast Routine started&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="o">*</span><span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="nx">rand</span><span class="p">.</span><span class="nf">Int</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">slowRoutine</span><span class="p">()(</span><span class="kt">int</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">	<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Slow Routine started&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="o">*</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="nx">rand</span><span class="p">.</span><span class="nf">Int</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// Created a WaitGroup</span>
</span></span><span class="line"><span class="cl">	<span class="kd">var</span> <span class="nx">wg</span> <span class="nx">sync</span><span class="p">.</span><span class="nx">WaitGroup</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c1">// Incrementing WaitGroup counter by 1</span>
</span></span><span class="line"><span class="cl">	<span class="nx">wg</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">go</span> <span class="kd">func</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">		<span class="c1">// Decrement WaitGroup counter by 1 </span>
</span></span><span class="line"><span class="cl">		<span class="c1">// after the goroutine is finished</span>
</span></span><span class="line"><span class="cl">		<span class="k">defer</span> <span class="nx">wg</span><span class="p">.</span><span class="nf">Done</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fastRandomVal</span> <span class="o">:=</span> <span class="nf">fastRoutine</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Value received from fast routine:&#34;</span><span class="p">,</span> <span class="nx">fastRandomVal</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">}()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="nx">wg</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="k">go</span> <span class="kd">func</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">		<span class="k">defer</span> <span class="nx">wg</span><span class="p">.</span><span class="nf">Done</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">		<span class="nx">slowRandomVal</span> <span class="o">:=</span> <span class="nf">slowRoutine</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">		<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Value received from slow routine:&#34;</span><span class="p">,</span> <span class="nx">slowRandomVal</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">	<span class="p">}()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c1">// Wait for the WaitGroup counter to reach 0</span>
</span></span><span class="line"><span class="cl">	<span class="nx">wg</span><span class="p">.</span><span class="nf">Wait</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Slow Routine started</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Fast Routine started</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Value received from fast routine: 4966166931659874487</span>
</span></span><span class="line"><span class="cl"><span class="c1">// Value received from slow routine: 439978995889306642</span>
</span></span></code></pre></div><p><code>WaitGroup</code> starts a counter at <code>0</code> and a delta (<code>int</code> value) is added to it using the <code>Add()</code> method. The <code>Done()</code> method decrements the counter by <code>1</code> and the <code>Wait()</code> method waits for the counter to reach <code>0</code> and moves to the next statements in the program.</p>
<h1 id="resources">Resources</h1>
<p><a href="https://freecontent.manning.com/concurrency-vs-parallelism/" target="_blank">Concurrency vs Parallelism</a><br>
<a href="https://youtu.be/oV9rvDllKEg" target="_blank">Concurrency is not Parallelism</a><br>
<a href="https://go.dev/talks/2012/waza.slide#29" target="_blank">[Slides] Concurrency is not Parallelism</a><br>
<a href="https://pkg.go.dev/github.com/eapache/channels" target="_blank">channels</a><br>
<a href="https://pkg.go.dev/sync#WaitGroup" target="_blank">WaitGroup</a></p>
]]></content:encoded>
    </item>
  </channel>
</rss>
