தமிழ்

Go-வின் கன்கரன்சி அம்சங்களுக்கான ஒரு முழுமையான வழிகாட்டி. திறமையான மற்றும் அளவிடக்கூடிய பயன்பாடுகளை உருவாக்குவதற்கான நடைமுறை எடுத்துக்காட்டுகளுடன் கோரூட்டீன்கள் மற்றும் சேனல்களை ஆராய்தல்.

Go கன்கரன்சி: கோரூட்டீன்கள் மற்றும் சேனல்களின் ஆற்றலை வெளிக்கொணர்தல்

Go, பெரும்பாலும் கோலாங் (Golang) என்று அழைக்கப்படுகிறது, அதன் எளிமை, செயல்திறன் மற்றும் கன்கரன்சிக்கான உள்ளமைக்கப்பட்ட ஆதரவிற்காகப் புகழ்பெற்றது. கன்கரன்சி நிரல்களை ஒரே நேரத்தில் பல பணிகளைச் செய்ய அனுமதிக்கிறது, இது செயல்திறனையும் மறுமொழியாற்றலையும் மேம்படுத்துகிறது. Go இந்தச் சாதனையை இரண்டு முக்கிய அம்சங்கள் மூலம் அடைகிறது: கோரூட்டீன்கள் மற்றும் சேனல்கள். இந்தக் வலைப்பதிவுப் பதிவு, இந்த அம்சங்களைப் பற்றிய ஒரு முழுமையான ஆய்வை வழங்குகிறது, அனைத்து நிலை டெவலப்பர்களுக்கும் நடைமுறை எடுத்துக்காட்டுகளையும் நுண்ணறிவுகளையும் வழங்குகிறது.

கன்கரன்சி என்றால் என்ன?

கன்கரன்சி என்பது ஒரு நிரல் ஒரே நேரத்தில் பல பணிகளைச் செய்யும் திறன் ஆகும். கன்கரன்சியை பேரலலிசத்திலிருந்து வேறுபடுத்துவது முக்கியம். கன்கரன்சி என்பது ஒரே நேரத்தில் பல பணிகளை *கையாள்வது* பற்றியது, அதே நேரத்தில் பேரலலிசம் என்பது ஒரே நேரத்தில் பல பணிகளை *செய்வது* பற்றியது. ஒரு ஒற்றை செயலி (processor) பணிகளுக்கு இடையில் வேகமாக மாறுவதன் மூலம் கன்கரன்சியை அடைய முடியும், இது ஒரே நேரத்தில் செயல்படுவது போன்ற ஒரு மாயையை உருவாக்குகிறது. மறுபுறம், பேரலலிசத்திற்கு, பணிகளை உண்மையாகவே ஒரே நேரத்தில் செயல்படுத்த பல செயலிகள் தேவை.

ஒரு உணவகத்தில் ஒரு சமையல்காரரைக் கற்பனை செய்து பாருங்கள். கன்கரன்சி என்பது காய்கறிகளை நறுக்குதல், சாஸ்களைக் கிளறுதல், மற்றும் இறைச்சியை வறுத்தல் போன்ற பணிகளுக்கு இடையில் மாறி மாறி பல ஆர்டர்களை நிர்வகிக்கும் சமையல்காரரைப் போன்றது. பேரலலிசம் என்பது பல சமையல்காரர்கள் ஒரே நேரத்தில் ஒவ்வொருவரும் வெவ்வேறு ஆர்டர்களில் வேலை செய்வதைப் போன்றது.

Go-வின் கன்கரன்சி மாடல், ஒரு ஒற்றை செயலி அல்லது பல செயலிகளில் இயங்கினாலும், கன்கரன்ட் நிரல்களை எழுதுவதை எளிதாக்குவதில் கவனம் செலுத்துகிறது. இந்த நெகிழ்வுத்தன்மை, அளவிடக்கூடிய மற்றும் திறமையான பயன்பாடுகளை உருவாக்குவதற்கான ஒரு முக்கிய நன்மையாகும்.

கோரூட்டீன்கள்: இலகுரக த்ரெட்கள்

ஒரு கோரூட்டீன் என்பது இலகுரக, சுதந்திரமாக இயங்கும் ஒரு ஃபங்ஷன் ஆகும். இதை ஒரு த்ரெட் என்று நினைத்துப் பாருங்கள், ஆனால் மிகவும் திறமையானது. ஒரு கோரூட்டீனை உருவாக்குவது நம்பமுடியாத அளவிற்கு எளிது: ஒரு ஃபங்ஷன் அழைப்புக்கு முன் `go` என்ற முக்கிய சொல்லைச் சேர்த்தால் போதும்.

கோரூட்டீன்களை உருவாக்குதல்

இங்கே ஒரு அடிப்படை எடுத்துக்காட்டு:

package main

import (
	"fmt"
	"time"
)

func sayHello(name string) {
	for i := 0; i < 5; i++ {
		fmt.Printf("Hello, %s! (Iteration %d)\n", name, i)
		time.Sleep(100 * time.Millisecond)
	}
}

func main() {
	go sayHello("Alice")
	go sayHello("Bob")

	// Wait for a short time to allow goroutines to execute
	time.Sleep(500 * time.Millisecond)
	fmt.Println("Main function exiting")
}

இந்த எடுத்துக்காட்டில், `sayHello` ஃபங்ஷன் இரண்டு தனித்தனி கோரூட்டீன்களாகத் தொடங்கப்படுகிறது, ஒன்று "Alice"க்காகவும் மற்றொன்று "Bob"க்காகவும். `main` ஃபங்ஷனில் உள்ள `time.Sleep` முக்கியமானது, ஏனெனில் பிரதான ஃபங்ஷன் வெளியேறும் முன் கோரூட்டீன்கள் செயல்படுவதற்கு நேரம் இருப்பதை இது உறுதி செய்கிறது. அது இல்லாமல், கோரூட்டீன்கள் முடிவடைவதற்கு முன்பே நிரல் முடிவடையக்கூடும்.

கோரூட்டீன்களின் நன்மைகள்

சேனல்கள்: கோரூட்டீன்களுக்கு இடையேயான தொடர்பு

கோரூட்டீன்கள் கோடை ஒரே நேரத்தில் இயக்க ஒரு வழியை வழங்கினாலும், அவை ஒன்றுக்கொன்று தொடர்பு கொள்ளவும், ஒத்திசைக்கவும் அடிக்கடி தேவைப்படுகின்றன. இங்குதான் சேனல்கள் வருகின்றன. ஒரு சேனல் என்பது ஒரு வகைப்படுத்தப்பட்ட வழித்தடமாகும், இதன் மூலம் நீங்கள் கோரூட்டீன்களுக்கு இடையில் மதிப்புகளை அனுப்பலாம் மற்றும் பெறலாம்.

சேனல்களை உருவாக்குதல்

சேனல்கள் `make` ஃபங்ஷனைப் பயன்படுத்தி உருவாக்கப்படுகின்றன:

ch := make(chan int) // முழு எண்களை அனுப்பக்கூடிய ஒரு சேனலை உருவாக்குகிறது

நீங்கள் பஃபர்டு சேனல்களையும் உருவாக்கலாம், அவை பெறுநர் தயாராக இல்லாமல் ஒரு குறிப்பிட்ட எண்ணிக்கையிலான மதிப்புகளை வைத்திருக்க முடியும்:

ch := make(chan int, 10) // 10 கொள்ளளவு கொண்ட ஒரு பஃபர்டு சேனலை உருவாக்குகிறது

தரவை அனுப்புதல் மற்றும் பெறுதல்

ஒரு சேனலுக்கு தரவு `<-` ஆபரேட்டரைப் பயன்படுத்தி அனுப்பப்படுகிறது:

ch <- 42 // 42 என்ற மதிப்பை ch என்ற சேனலுக்கு அனுப்புகிறது

ஒரு சேனலில் இருந்து தரவு `<-` ஆபரேட்டரைப் பயன்படுத்தியே பெறப்படுகிறது:

value := <-ch // ch என்ற சேனலில் இருந்து ஒரு மதிப்பைப் பெற்று அதை value என்ற மாறியில் சேமிக்கிறது

எடுத்துக்காட்டு: கோரூட்டீன்களை ஒருங்கிணைக்க சேனல்களைப் பயன்படுத்துதல்

கோரூட்டீன்களை ஒருங்கிணைக்க சேனல்களை எவ்வாறு பயன்படுத்தலாம் என்பதைக் காட்டும் ஒரு எடுத்துக்காட்டு இங்கே:

package main

import (
	"fmt"
	"time"
)

func worker(id int, jobs <-chan int, results chan<- int) {
	for j := range jobs {
		fmt.Printf("Worker %d started job %d\n", id, j)
		time.Sleep(time.Second)
		fmt.Printf("Worker %d finished job %d\n", id, j)
		results <- j * 2
	}
}

func main() {
	jobs := make(chan int, 100)
	results := make(chan int, 100)

	// Start 3 worker goroutines
	for w := 1; w <= 3; w++ {
		go worker(w, jobs, results)
	}

	// Send 5 jobs to the jobs channel
	for j := 1; j <= 5; j++ {
		jobs <- j
	}
	close(jobs)

	// Collect the results from the results channel
	for a := 1; a <= 5; a++ {
		fmt.Println("Result:", <-results)
	}
}

இந்த எடுத்துக்காட்டில்:

இந்த எடுத்துக்காட்டு, பல கோரூட்டீன்களுக்கு இடையில் வேலையைப் பகிர்ந்து, முடிவுகளைச் சேகரிக்க சேனல்களை எவ்வாறு பயன்படுத்தலாம் என்பதைக் காட்டுகிறது. `jobs` சேனலை மூடுவது, பணியாளர் கோரூட்டீன்களுக்கு இனி வேலைகள் இல்லை என்பதைக் குறிக்க மிகவும் முக்கியமானது. சேனலை மூடவில்லை என்றால், பணியாளர் கோரூட்டீன்கள் மேலும் வேலைகளுக்காக காலவரையின்றித் தடுக்கப்படும்.

செலக்ட் ஸ்டேட்மென்ட்: பல சேனல்களில் மல்டிபிளெக்சிங்

`select` ஸ்டேட்மென்ட் பல சேனல் செயல்பாடுகளில் ஒரே நேரத்தில் காத்திருக்க உங்களை அனுமதிக்கிறது. கேஸ்களில் ஒன்று தொடரத் தயாராகும் வரை அது பிளாக் செய்யும். பல கேஸ்கள் தயாராக இருந்தால், ஒன்று தோராயமாகத் தேர்ந்தெடுக்கப்படும்.

எடுத்துக்காட்டு: பல சேனல்களைக் கையாள செலக்ட் பயன்படுத்துதல்

package main

import (
	"fmt"
	"time"
)

func main() {
	c1 := make(chan string, 1)
	c2 := make(chan string, 1)

	go func() {
		time.Sleep(2 * time.Second)
		c1 <- "Message from channel 1"
	}()

	go func() {
		time.Sleep(1 * time.Second)
		c2 <- "Message from channel 2"
	}()

	for i := 0; i < 2; i++ {
		select {
		case msg1 := <-c1:
			fmt.Println("Received:", msg1)
		case msg2 := <-c2:
			fmt.Println("Received:", msg2)
		case <-time.After(3 * time.Second):
			fmt.Println("Timeout")
			return
		}
	}
}

இந்த எடுத்துக்காட்டில்:

`select` ஸ்டேட்மென்ட் பல ஒரேநேர செயல்பாடுகளைக் கையாள்வதற்கும், ஒரு சேனலில் காலவரையின்றி பிளாக் செய்வதைத் தவிர்ப்பதற்கும் ஒரு சக்திவாய்ந்த கருவியாகும். `time.After` ஃபங்ஷன் காலக்கெடுவை செயல்படுத்துவதற்கும் டெப்லாக்குகளைத் தடுப்பதற்கும் குறிப்பாக பயனுள்ளதாக இருக்கும்.

Go-வில் பொதுவான கன்கரன்சி பேட்டர்ன்கள்

Go-வின் கன்கரன்சி அம்சங்கள் பல பொதுவான பேட்டர்ன்களுக்கு வழிவகுக்கின்றன. இந்த பேட்டர்ன்களைப் புரிந்துகொள்வது மேலும் வலுவான மற்றும் திறமையான கன்கரன்ட் கோடை எழுத உதவும்.

பணியாளர் குளங்கள் (Worker Pools)

முந்தைய எடுத்துக்காட்டில் காட்டியபடி, பணியாளர் குளங்கள் ஒரு பகிரப்பட்ட வரிசையிலிருந்து (சேனல்) பணிகளைச் செயல்படுத்தும் ஒரு தொகுதி பணியாளர் கோரூட்டீன்களை உள்ளடக்கியது. இந்த பேட்டர்ன் பல செயலிகளுக்கு வேலையைப் பகிர்வதற்கும், செயல்திறனை மேம்படுத்துவதற்கும் பயனுள்ளதாக இருக்கும். எடுத்துக்காட்டுகள் பின்வருமாறு:

ஃபேன்-அவுட், ஃபேன்-இன் (Fan-out, Fan-in)

இந்த பேட்டர்ன் வேலையை பல கோரூட்டீன்களுக்கு விநியோகிப்பதையும் (ஃபேன்-அவுட்) பின்னர் முடிவுகளை ஒரு சேனலில் ஒருங்கிணைப்பதையும் (ஃபேன்-இன்) உள்ளடக்கியது. இது பெரும்பாலும் தரவை இணையாகச் செயலாக்கப் பயன்படுத்தப்படுகிறது.

ஃபேன்-அவுட்: தரவை ஒரே நேரத்தில் செயலாக்க பல கோரூட்டீன்கள் உருவாக்கப்படுகின்றன. ஒவ்வொரு கோரூட்டீனும் செயலாக்க வேண்டிய தரவின் ஒரு பகுதியைப் பெறுகிறது.

ஃபேன்-இன்: ஒரு ஒற்றை கோரூட்டீன் அனைத்து பணியாளர் கோரூட்டீன்களிலிருந்தும் முடிவுகளைச் சேகரித்து அவற்றை ஒரே முடிவாக ஒருங்கிணைக்கிறது. இது பெரும்பாலும் பணியாளர்களிடமிருந்து முடிவுகளைப் பெற ஒரு சேனலைப் பயன்படுத்துவதை உள்ளடக்கியது.

எடுத்துக்காட்டு காட்சிகள்:

பைப்லைன்கள் (Pipelines)

ஒரு பைப்லைன் என்பது தொடர்ச்சியான நிலைகளின் ஒரு தொடராகும், அங்கு ஒவ்வொரு நிலையும் முந்தைய நிலையிலிருந்து தரவைச் செயலாக்கி, முடிவை அடுத்த நிலைக்கு அனுப்புகிறது. இது சிக்கலான தரவு செயலாக்க பணிப்பாய்வுகளை உருவாக்கப் பயன்படுகிறது. ஒவ்வொரு நிலையும் பொதுவாக அதன் சொந்த கோரூட்டீனில் இயங்குகிறது மற்றும் சேனல்கள் வழியாக மற்ற நிலைகளுடன் தொடர்பு கொள்கிறது.

எடுத்துக்காட்டு பயன்பாட்டு வழக்குகள்:

கன்கரன்ட் Go நிரல்களில் பிழை கையாளுதல்

கன்கரன்ட் நிரல்களில் பிழை கையாளுதல் மிகவும் முக்கியமானது. ஒரு கோரூட்டீன் ஒரு பிழையை எதிர்கொள்ளும்போது, அதைச் சரியாகக் கையாள்வதும், அது முழு நிரலையும் செயலிழக்கச் செய்வதைத் தடுப்பதும் முக்கியம். இதோ சில சிறந்த நடைமுறைகள்:

எடுத்துக்காட்டு: சேனல்களுடன் பிழை கையாளுதல்

package main

import (
	"fmt"
	"time"
)

func worker(id int, jobs <-chan int, results chan<- int, errs chan<- error) {
	for j := range jobs {
		fmt.Printf("Worker %d started job %d\n", id, j)
		time.Sleep(time.Second)
		fmt.Printf("Worker %d finished job %d\n", id, j)
		if j%2 == 0 { // Simulate an error for even numbers
			errs <- fmt.Errorf("Worker %d: Job %d failed", id, j)
			results <- 0 // Send a placeholder result
		} else {
			results <- j * 2
		}
	}
}

func main() {
	jobs := make(chan int, 100)
	results := make(chan int, 100)
	errs := make(chan error, 100)

	// Start 3 worker goroutines
	for w := 1; w <= 3; w++ {
		go worker(w, jobs, results, errs)
	}

	// Send 5 jobs to the jobs channel
	for j := 1; j <= 5; j++ {
		jobs <- j
	}
	close(jobs)

	// Collect the results and errors
	for a := 1; a <= 5; a++ {
		select {
		case res := <-results:
			fmt.Println("Result:", res)
		case err := <-errs:
			fmt.Println("Error:", err)
		}
	}
}

இந்த எடுத்துக்காட்டில், பணியாளர் கோரூட்டீன்களிலிருந்து பிரதான ஃபங்ஷனுக்கு பிழைச் செய்திகளை அனுப்ப `errs` என்ற சேனலைச் சேர்த்துள்ளோம். பணியாளர் கோரூட்டீன் இரட்டைப்படை எண்களுக்கான வேலைகளுக்கு ஒரு பிழையை உருவகப்படுத்துகிறது, `errs` சேனலில் ஒரு பிழைச் செய்தியை அனுப்புகிறது. பிரதான ஃபங்ஷன் பின்னர் ஒவ்வொரு பணியாளர் கோரூட்டீனிலிருந்தும் ஒரு முடிவு அல்லது ஒரு பிழையைப் பெற `select` ஸ்டேட்மென்ட்டைப் பயன்படுத்துகிறது.

ஒத்திசைவு ப்ரிமிட்டிவ்கள்: மியூடெக்ஸ்கள் மற்றும் வெய்ட்குரூப்கள்

கோரூட்டீன்களுக்கு இடையில் தொடர்பு கொள்ள சேனல்கள் விரும்பத்தக்க வழியாக இருந்தாலும், சில நேரங்களில் பகிரப்பட்ட வளங்களின் மீது உங்களுக்கு நேரடிக் கட்டுப்பாடு தேவைப்படலாம். இந்த நோக்கத்திற்காக Go, மியூடெக்ஸ்கள் மற்றும் வெய்ட்குரூப்கள் போன்ற ஒத்திசைவு ப்ரிமிட்டிவ்களை வழங்குகிறது.

மியூடெக்ஸ்கள்

ஒரு மியூடெக்ஸ் (மியூச்சுவல் எக்ஸ்க்ளூஷன் லாக்) பகிரப்பட்ட வளங்களை ஒரேநேர அணுகலில் இருந்து பாதுகாக்கிறது. ஒரே நேரத்தில் ஒரு கோரூட்டீன் மட்டுமே பூட்டை வைத்திருக்க முடியும். இது தரவுப் போட்டிகளைத் தடுக்கிறது மற்றும் தரவு நிலைத்தன்மையை உறுதி செய்கிறது.

package main

import (
	"fmt"
	"sync"
)

var ( // shared resource
	counter int
	m sync.Mutex
)

func increment() {
	m.Lock() // Acquire the lock
	counter++
	fmt.Println("Counter incremented to:", counter)
	m.Unlock() // Release the lock
}

func main() {
	var wg sync.WaitGroup

	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			increment()
		}()
	}

	wg.Wait() // Wait for all goroutines to finish
	fmt.Println("Final counter value:", counter)
}

இந்த எடுத்துக்காட்டில், `increment` ஃபங்ஷன் `counter` மாறியை ஒரேநேர அணுகலில் இருந்து பாதுகாக்க ஒரு மியூடெக்ஸைப் பயன்படுத்துகிறது. `m.Lock()` முறை கவுண்டரை அதிகரிப்பதற்கு முன் பூட்டைப் பெறுகிறது, மற்றும் `m.Unlock()` முறை கவுண்டரை அதிகரித்த பிறகு பூட்டை விடுவிக்கிறது. இது ஒரே நேரத்தில் ஒரு கோரூட்டீன் மட்டுமே கவுண்டரை அதிகரிக்க முடியும் என்பதை உறுதி செய்கிறது, தரவுப் போட்டிகளைத் தடுக்கிறது.

வெய்ட்குரூப்கள்

ஒரு வெய்ட்குரூப் என்பது ஒரு தொகுதி கோரூட்டீன்கள் முடிவடையும் வரை காத்திருக்கப் பயன்படுகிறது. இது மூன்று மெத்தட்களை வழங்குகிறது:

முந்தைய எடுத்துக்காட்டில், `sync.WaitGroup` ஆனது, இறுதி கவுண்டர் மதிப்பை அச்சிடுவதற்கு முன்பு, 100 கோரூட்டீன்களும் முடிவடையும் வரை பிரதான ஃபங்ஷன் காத்திருப்பதை உறுதி செய்கிறது. `wg.Add(1)` ஒவ்வொரு தொடங்கப்பட்ட கோரூட்டீனுக்கும் கவுண்டரை அதிகரிக்கிறது. `defer wg.Done()` ஒரு கோரூட்டீன் முடிந்ததும் கவுண்டரைக் குறைக்கிறது, மற்றும் `wg.Wait()` அனைத்து கோரூட்டீன்களும் முடியும் வரை (கவுண்டர் பூஜ்ஜியத்தை அடையும் வரை) பிளாக் செய்கிறது.

கான்டெக்ஸ்ட்: கோரூட்டீன்களை நிர்வகித்தல் மற்றும் ரத்து செய்தல்

`context` பேக்கேஜ் கோரூட்டீன்களை நிர்வகிக்கவும் ரத்து செய்தல் சிக்னல்களைப் பரப்பவும் ஒரு வழியை வழங்குகிறது. இது நீண்டகால செயல்பாடுகள் அல்லது வெளிப்புற நிகழ்வுகளின் அடிப்படையில் ரத்து செய்யப்பட வேண்டிய செயல்பாடுகளுக்கு குறிப்பாக பயனுள்ளதாக இருக்கும்.

எடுத்துக்காட்டு: ரத்து செய்ய கான்டெக்ஸ்டைப் பயன்படுத்துதல்

package main

import (
	"context"
	"fmt"
	"time"
)

func worker(ctx context.Context, id int) {
	for {
		select {
		case <-ctx.Done():
			fmt.Printf("Worker %d: Canceled\n", id)
			return
		default:
			fmt.Printf("Worker %d: Working...\n", id)
			time.Sleep(time.Second)
		}
	}
}

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	// Start 3 worker goroutines
	for w := 1; w <= 3; w++ {
		go worker(ctx, w)
	}

	// Cancel the context after 5 seconds
	time.Sleep(5 * time.Second)
	fmt.Println("Canceling context...")
	cancel()

	// Wait for a while to allow workers to exit
	time.Sleep(2 * time.Second)
	fmt.Println("Main function exiting")
}

இந்த எடுத்துக்காட்டில்:

கான்டெக்ஸ்ட்களைப் பயன்படுத்துவது, கோரூட்டீன்கள் இனி தேவைப்படாதபோது அவற்றைச் சரியாக மூடுவதற்கு உங்களை அனுமதிக்கிறது, வளக் கசிவுகளைத் தடுத்து, உங்கள் நிரல்களின் நம்பகத்தன்மையை மேம்படுத்துகிறது.

Go கன்கரன்சியின் நிஜ உலகப் பயன்பாடுகள்

Go-வின் கன்கரன்சி அம்சங்கள் பரந்த அளவிலான நிஜ உலகப் பயன்பாடுகளில் பயன்படுத்தப்படுகின்றன, அவற்றுள்:

Go கன்கரன்சிக்கான சிறந்த நடைமுறைகள்

கன்கரன்ட் Go நிரல்களை எழுதும்போது மனதில் கொள்ள வேண்டிய சில சிறந்த நடைமுறைகள் இங்கே:

முடிவுரை

Go-வின் கன்கரன்சி அம்சங்கள், குறிப்பாக கோரூட்டீன்கள் மற்றும் சேனல்கள், கன்கரன்ட் மற்றும் பேரலல் பயன்பாடுகளை உருவாக்க ஒரு சக்திவாய்ந்த மற்றும் திறமையான வழியை வழங்குகின்றன. இந்த அம்சங்களைப் புரிந்துகொண்டு சிறந்த நடைமுறைகளைப் பின்பற்றுவதன் மூலம், நீங்கள் வலுவான, அளவிடக்கூடிய மற்றும் உயர் செயல்திறன் கொண்ட நிரல்களை எழுதலாம். இந்த கருவிகளை திறம்படப் பயன்படுத்தும் திறன், நவீன மென்பொருள் மேம்பாட்டிற்கு, குறிப்பாக விநியோகிக்கப்பட்ட அமைப்புகள் மற்றும் கிளவுட் கம்ப்யூட்டிங் சூழல்களில் ஒரு முக்கியமான திறமையாகும். Go-வின் வடிவமைப்பு, புரிந்துகொள்ள எளிதான மற்றும் செயல்படுத்த திறமையான கன்கரன்ட் கோடை எழுதுவதை ஊக்குவிக்கிறது.

Go கன்கரன்சி: கோரூட்டீன்கள் மற்றும் சேனல்களின் ஆற்றலை வெளிக்கொணர்தல் | MLOG