Go Language Competitiveness Part I

If you are involved in programming, you must have wanted to speed up your code by taking advantage of the capabilities of modern multi-core processors. One way is to schedule program execution across multiple cores. Writing competing programs has always been a challenge until the Go programming language came on the scene and made this simpler.

Introduction
Go is an open-source programming language developed by Google. In addition to Google, a number of global companies are using Go in their development, with only a few being Facebook, DropBox, Basecamp, and Cloudflare. The two largest container development projects, Docker and Kubernetes, are written in the Go programming language. The syntax is similar to other scripting languages ​​and allows easy development of simple, reliable and efficient software. One of the main reasons why many of the world’s leading companies use the Go language, in addition to its speed, is the ease of developing competing programs. This article will focus on the basic principles of Go competitiveness. If you have not encountered this programming language, you can do your first steps simply at the following link. In addition to the official documentation, you can learn more about the basics of Go in some of the following links:

https://golangbot.com/
https://www.tutorialspoint.com/go/
https://www.youtube.com/watch?v=SqrbIlUwR0U

Installation

Before we begin the installation, make sure you have the latest Ubuntu packages installed on your computer. You can do this with the following commands:

sudo apt-get update
sudo apt-get -y upgrade

Now that you are sure that you have the latest packages installed on your computer, download the appropriate archive from the following link.

Extract the downloaded archive and then move it to the / usr / local folder:

tar -xvf go1.11.2.linux-amd64.tar.gz
sudo mv go /usr/local

In order to remember the path, we need to do the following

sudo nano ~ / .profile

And at the end of the file add the following lines

export GOPATH = $ HOME/work
export PATH = $ PATH: /usr/local/go/bin: $ GOPATH/bin

To keep the path memorized, the following command must be executed

source ~ / .profile

To make sure the installation was successful, type in the terminal

go version

If all is successful, you will receive feedback on the version of Go that is installed on your computer.

The keyword go

If you want a function to run as a separate thread, all you have to do is add the go keyword before the function call:

func main () {
   go doSomething ()
}

All threads are executed in the same address space, so access to shared memory must be provided. Now let’s consider one simple example:

package main

import (
     “fmt”
)

func doSomething () {
     fmt.Println (“to something”)
}

func main () {
     fmt.Println (“start”)
     doSomething ()
     fmt.Println (“end”)
}

To run the program, you need to save it in the first.go file and type go run first.go at the command line. The output of the program is as follows:

start
to something
end

This was quite predictable, because everything is executed in the order in which it is written. We will now allow the doSomething function to be executed as a separate thread.

func main () {
     fmt.Println (“start”)
     go doSomething ()
     fmt.Println (“end”)
}

By running the modified program, we will probably get the following output:

start
end

What actually happened here? And why probably? In Go, when the main function is completed, the entire program ends. In the program above, the thread that performs the doSomething function did not receive any CPU time at all before the program ended.

The sync package

The standard library provides us with a sync package, which provides us with some basic tools for synchronizing and providing a critical section. WaitGroup is essentially a counter that we magnify when we wait for a thread to execute, or diminish, when the thread has finished its work. Thus, we can delay the execution of a specific part of the program until the counter value is zero, which means that all threads have completed their work. Edit the previous program to look like the following:

package main

import (
   “fmt”
   “sync”
)

var wg sync.WaitGroup

func main () {
   fmt.Println (“start”)
   wg.Add (1) // tells us that we want to wait for one thread to finish its job
   go doSomething ()
   fmt.Println (“end”)
   wg.Wait () // We are waiting for the thread to finish its job
   // end of program
}
func doSomething () {
   fmt.Println (“to something”)
   wg.Done () // thread has finished its job
}

Key parts of the code are explained:

var wg sync.WaitGroup – define a WaitGroup object whose initial value is zero,
wg.Add (1) – we are saying that there is a thread whose execution needs to wait (in our case the doSomething function),
wg.Wait () – tells the program to block until the WaitGroup counter reaches zero,
wg.Done () – Says the thread did its job.

Restart the program and you will probably get the following output:

start
end
to something

This time the main program waited for the background thread to execute and then interrupted its execution. However, the order of execution is still unpredictable. When we ask for a program to be executed competitively, we cannot say exactly how and when the instructions will be executed, which can lead to an unpredictable order of execution. As long as we understand why this is happening, it does not pose a problem in the development of competing programs. We have seen that the basic development of a competitive Go program is not too difficult, since all you have to do is add the keyword go. In the next section, we will cover the more advanced concepts of Go competitiveness and explain all of these with adequate examples.

Useful links


                        
Likes:
9 0
Views:
1208
Article Categories:
PROGRAMMINGTECHNOLOGY

Leave a Reply

Your email address will not be published. Required fields are marked *