Golang Concurrency

Конкуренция Голанга

Конкуренция — это способность программы выполнять несколько действий одновременно. Это значтт, что в программе две или более задач выполняются независимо друг от друга примерно в одно и то же время, но при этом остаются частью одной и той же программы. Конкуренция очень важен в современном программировании из-за необходимости выполнять независимые фрагменты кода как можно быстрее, не нарушая общий ход программы.

Конкуренция в Golang — это возможность функций работать независимо друг от друга. Горутина — это функция, которая может работать одновременно с другими функциями. Когда вы создаете функцию как горутину, она рассматривается как независимая единица работы, которая планируется, а затем выполняется на доступном логическом процессоре. Планировщик времени выполнения Golang имеет функцию управления всеми горутинами, которые требуют процессорного времени для выполненния. Планировщик привязывает потоки операционной системы к логическим процессорам для выполнения горутин. Планировщик контролирует все, что связано с тем, какие горутины выполняются на каких логических процессорах в любой момент времени.

Параллельная программа потенциально выполняется быстрее, чем последовательная программа, поскольку различные части вычислений выполняются одновременно (параллельно). Он может иметь или не иметь более одного логического потока управления.

package main

import (
	"hash/fnv"
	"log"
	"math/rand"
	"os"
	"sync"
	"time"
)

// Number of philosophers is simply the length of this list.
var ph = []string{"Mark", "Russell", "Rocky", "Haris", "Root"}

const hunger = 3                // Number of times each philosopher eats
const think = time.Second / 100 // Mean think time
const eat = time.Second / 100   // Mean eat time

var fmt = log.New(os.Stdout, "", 0)

var dining sync.WaitGroup

func diningProblem(phName string, dominantHand, otherHand *sync.Mutex) {
	fmt.Println(phName, "Seated")
	h := fnv.New64a()
	h.Write([]byte(phName))
	rg := rand.New(rand.NewSource(int64(h.Sum64())))
	rSleep := func(t time.Duration) {
		time.Sleep(t/2 + time.Duration(rg.Int63n(int64(t))))
	}
	for h := hunger; h > 0; h-- {
		fmt.Println(phName, "Hungry")
		dominantHand.Lock() // pick up forks
		otherHand.Lock()
		fmt.Println(phName, "Eating")
		rSleep(eat)
		dominantHand.Unlock() // put down forks
		otherHand.Unlock()
		fmt.Println(phName, "Thinking")
		rSleep(think)
	}
	fmt.Println(phName, "Satisfied")
	dining.Done()
	fmt.Println(phName, "Left the table")
}

func main() {
	fmt.Println("Table empty")
	dining.Add(5)
	fork0 := &sync.Mutex{}
	forkLeft := fork0
	for i := 1; i < len(ph); i++ {
		forkRight := &sync.Mutex{}
		go diningProblem(ph[i], forkLeft, forkRight)
		forkLeft = forkRight
	}
	go diningProblem(ph[0], fork0, forkLeft)
	dining.Wait() // wait for philosphers to finish
	fmt.Println("Table empty")
}

Вывод:

Table empty
Mark seated
Mark Hungry
Mark Eating
..................
..................
Haris Thinking
Haris Satisfied
Haris Left the table
Table empty

Ответить