In Go, goroutines are a lightweight way to achieve concurrency. A goroutine is a function that runs concurrently with other goroutines in the same program. They are cheaper in terms of memory and resources compared to traditional threads, making them a powerful tool for writing concurrent programs.
Here’s a detailed explanation of goroutines with examples.
You can start a goroutine by using the go
keyword before a function call. When you do this, the function runs concurrently as a goroutine.
🔹 Example:
package main
import (
"fmt"
"time"
)
// A simple function
func printMessage(msg string) {
fmt.Println(msg)
}
func main() {
// Starting a goroutine
go printMessage("Hello, Goroutines!")
// Adding a sleep to allow goroutine to finish before main exits
time.Sleep(time.Second)
}
🔹 Output:
Hello, Goroutines!
👉 In this example, printMessage
runs concurrently as a goroutine. Without time.Sleep
, the main function might exit before the goroutine finishes, so we add a delay to give it time.
You can also start goroutines with anonymous functions.
🔹 Example:
package main
import (
"fmt"
"time"
)
func main() {
// Starting a goroutine with an anonymous function
go func() {
fmt.Println("Running an anonymous function as a goroutine!")
}()
time.Sleep(time.Second)
}
🔹 Output:
Running an anonymous function as a goroutine!
👉 This shows how anonymous functions can be run as goroutines for quick concurrent tasks.
Goroutines can accept parameters like regular functions. However, you need to be careful about variable scopes when using goroutines inside loops or with shared data.
🔹 Example:
package main
import (
"fmt"
"time"
)
func printNumbers(num int) {
fmt.Println(num)
}
func main() {
for i := 1; i <= 5; i++ {
go printNumbers(i) // Passing loop variable to goroutine
}
time.Sleep(time.Second)
}
🔹 Output: (The order of output may vary)
1
2
3
4
5
👉 Each goroutine receives the current value of i
and prints it. Since goroutines are concurrent, the order of output may not always be sequential.
Because goroutines run concurrently, you often need to synchronize their execution to ensure they finish correctly. You can use WaitGroups from the sync
package to wait for multiple goroutines to finish.
🔹 Example (Using WaitGroup):
package main
import (
"fmt"
"sync"
)
func printMessage(msg string, wg *sync.WaitGroup) {
fmt.Println(msg)
wg.Done() // Mark the goroutine as done
}
func main() {
var wg sync.WaitGroup
messages := []string{"Hello", "World", "Goroutines", "Are", "Fun"}
// Adding the number of goroutines to wait for
wg.Add(len(messages))
for _, msg := range messages {
go printMessage(msg, &wg)
}
// Wait for all goroutines to finish
wg.Wait()
}
🔹 Output: (Order may vary)
Hello
World
Goroutines
Are
Fun
👉 Here, WaitGroup
ensures that the main function waits for all goroutines to finish before exiting.
Channels are a way to communicate between goroutines. One goroutine can send data through a channel, and another goroutine can receive data from the channel.
🔹 Example (Using Channels):
package main
import "fmt"
// Function that sends data to a channel
func sendMessage(ch chan string) {
ch <- "Hello from a goroutine!"
}
func main() {
ch := make(chan string)
go sendMessage(ch) // Start a goroutine
// Receive the message from the channel
msg := <-ch
fmt.Println(msg)
}
🔹 Output:
Hello from a goroutine!
👉 The sendMessage
function sends data to the channel, and the main function receives it, allowing goroutines to communicate safely.
go
keyword.WaitGroup
.Goroutines provide a powerful and efficient way to handle concurrency in Go, making it easy to run multiple tasks simultaneously without much overhead.
Go প্রোগ্রামিং ভাষায়, goroutines হল হালকা ওজনের একটি উপায় কনকারেন্সি (concurrency) অর্জনের জন্য। একটি goroutine একটি ফাংশন যা অন্যান্য goroutines-এর সাথে একই সময়ে চলে। এটি সাধারণ থ্রেডের তুলনায় অনেক কম মেমরি ও রিসোর্স ব্যবহার করে, যার ফলে কার্যকরভাবে একাধিক কাজ একসাথে সম্পাদন করা সম্ভব।
নিচে goroutines নিয়ে বিস্তারিত আলোচনা এবং উদাহরণ দেয়া হলো।
go
কিওয়ার্ড ব্যবহার করে goroutine শুরু করা যায়। যখন আপনি go
কিওয়ার্ড দিয়ে কোনো ফাংশন কল করেন, তখন ফাংশনটি একটি goroutine হিসেবে সমান্তরালে (concurrently) চলে।
🔹 উদাহরণ:
package main
import (
"fmt"
"time"
)
// একটি সহজ ফাংশন
func printMessage(msg string) {
fmt.Println(msg)
}
func main() {
// একটি goroutine শুরু করা
go printMessage("Hello, Goroutines!")
// goroutine শেষ হওয়ার জন্য সময় দেয়া (main ফাংশন বন্ধ হওয়ার আগে)
time.Sleep(time.Second)
}
🔹 আউটপুট:
Hello, Goroutines!
👉 এই উদাহরণে, printMessage
ফাংশনটি goroutine হিসেবে চলে। যদি time.Sleep
না দেয়া হয়, তাহলে main ফাংশন goroutine শেষ হওয়ার আগেই বন্ধ হয়ে যেতে পারে, তাই একটি বিলম্ব যোগ করা হয়েছে।
অ্যানোনিমাস ফাংশন ব্যবহার করে সরাসরি goroutine শুরু করা যায়।
🔹 উদাহরণ:
package main
import (
"fmt"
"time"
)
func main() {
// অ্যানোনিমাস ফাংশন দিয়ে goroutine শুরু করা
go func() {
fmt.Println("Running an anonymous function as a goroutine!")
}()
time.Sleep(time.Second)
}
🔹 আউটপুট:
Running an anonymous function as a goroutine!
👉 এখানে, অ্যানোনিমাস ফাংশন দ্রুত ছোট কাজের জন্য goroutine হিসেবে ব্যবহার করা হয়েছে।
গরুটিনে সাধারণ ফাংশনের মতো প্যারামিটারও পাঠানো যায়। তবে, লুপের মধ্যে বা শেয়ার করা ডেটা ব্যবহার করার সময় সতর্ক থাকা উচিত, কারণ কনকারেন্সি জনিত সমস্যা হতে পারে।
🔹 উদাহরণ:
package main
import (
"fmt"
"time"
)
func printNumbers(num int) {
fmt.Println(num)
}
func main() {
for i := 1; i <= 5; i++ {
go printNumbers(i) // লুপের ভ্যারিয়েবল পাঠানো হচ্ছে goroutine-এ
}
time.Sleep(time.Second)
}
🔹 আউটপুট: (আউটপুটের ক্রম পরিবর্তিত হতে পারে)
1
2
3
4
5
👉 এখানে প্রতিটি goroutine বর্তমান ভ্যালু নিয়ে কাজ করে এবং ভ্যালুগুলো প্রিন্ট করে। যেহেতু goroutines সমান্তরালে চলে, তাই আউটপুটের ক্রম সবসময় একই নাও হতে পারে।
goroutines একসাথে চলতে পারে বলে প্রোগ্রামের প্রধান অংশ থেকে তাদের সিঙ্ক্রোনাইজ করা প্রয়োজন হতে পারে। WaitGroup ব্যবহার করে একাধিক goroutines এর সমাপ্তির জন্য অপেক্ষা করা যায়।
🔹 উদাহরণ (Using WaitGroup):
package main
import (
"fmt"
"sync"
)
func printMessage(msg string, wg *sync.WaitGroup) {
fmt.Println(msg)
wg.Done() // goroutine কাজ শেষ
}
func main() {
var wg sync.WaitGroup
messages := []string{"Hello", "World", "Goroutines", "Are", "Fun"}
// অপেক্ষা করার জন্য goroutines এর সংখ্যা যোগ করা
wg.Add(len(messages))
for _, msg := range messages {
go printMessage(msg, &wg)
}
// সমস্ত goroutines এর শেষ হওয়ার জন্য অপেক্ষা
wg.Wait()
}
🔹 আউটপুট: (অর্ডার পরিবর্তিত হতে পারে)
Hello
World
Goroutines
Are
Fun
👉 এখানে, WaitGroup
ব্যবহার করে নিশ্চিত করা হয়েছে যে, মূল প্রোগ্রাম সব goroutines শেষ হওয়া পর্যন্ত অপেক্ষা করবে।
Channels ব্যবহার করে goroutines একে অপরের সাথে যোগাযোগ করতে পারে। একটি goroutine চ্যানেলের মাধ্যমে ডেটা পাঠাতে পারে এবং অন্য একটি goroutine সেই ডেটা গ্রহণ করতে পারে।
🔹 উদাহরণ (Using Channels):
package main
import "fmt"
// চ্যানেলে ডেটা পাঠানো ফাংশন
func sendMessage(ch chan string) {
ch <- "Hello from a goroutine!"
}
func main() {
ch := make(chan string)
go sendMessage(ch) // goroutine শুরু করা
// চ্যানেল থেকে মেসেজ গ্রহণ করা
msg := <-ch
fmt.Println(msg)
}
🔹 আউটপুট:
Hello from a goroutine!
👉 এখানে, sendMessage
ফাংশন চ্যানেলে ডেটা পাঠায় এবং মূল ফাংশন চ্যানেল থেকে সেই ডেটা গ্রহণ করে।
go
কিওয়ার্ড ব্যবহার করে goroutine শুরু করা হয়।Goroutines অত্যন্ত শক্তিশালী এবং কার্যকর উপায় কনকারেন্সি অর্জনের জন্য, যা একসাথে একাধিক কাজ সম্পাদন করতে সহায়তা করে।