Bài viết được sự cho phép của tác giả Kiên Nguyễn
Được biết tới là một trong những ngôn ngữ hỗ trợ mạnh mẽ concurrency, Golang Goroutines và Channels thật ra có ý nghĩa như thế nào?. Có sự khác biệt nào giữa Golang Concurrency và Java Concurrency hay không?.
Trước khi bắt đầu tìm hiểu sâu hơn, hãy cùng bắt đầu với hai khái niệm cơ bản nhất, Routines và Channels.
Ngoài ra, golang cũng hỗ trợ functional programming. Có thể tìm hiểu qua về functional programming qua bài viết này.
Ok, bắt đầu ngay thôi!
1. Concurrency
Trước khi bắt đầu tìm hiểu Routines và Channels, hãy nắm bắt khái niệm về Concurrency (Tính toán đồng thời).
Making process on more than one task simultaneously is known as concurrency
Việc thực hiện nhiều hơn một task trên một process được biết tới là concurrency (đồng thời, cùng lúc)
Đã hiểu về Concurrency, tuy nhiên nhớ take note luôn là nó khác biệt hoàn toàn với Parallel. Thực hiện mọi việc đồng thời, nhưng có thể chỉ ở trên cùng một core, một process của CPU.
Parallel lại tận dụng đa lõi, thực hiện mọi việc đồng thời, nhưng trên nhiều tiến trình.
2. Goroutines
Muốn một function có thể chạy đồng thời với function tất nhiên phải có khai báo. Không khai báo thì Go không thể biết được khi nào function đó được chạy Concurrency.
A goroutine is a function that is capable of running concurrently with other functions
Goroutine là function có thể chạy đồng thời với các function khác
Để khai báo một function sử dụng Routines, ta dùng từ khóa go.
// Function go f(0) được thực hiện đồng thời package main import "fmt" func f(n int) { for i := 0; i < 10; i++ { fmt.Println(n, ":", i) } } func main() { go f(0) var input string fmt.Scanln(&input) }
Đoạn code vừa viết phía trên có tới hai Goroutines. Cái đầu tiên tất nhiên là function main, tự bản thân nó đã là một Goroutines. Cái thứ hai sẽ được khởi tạo khi ta gọi function go f(0).
Ở các chương trình Java thông thường (hoặc Golang mà không có sử dụng từ khóa go). Dòng code số 11 sẽ được thực thi sau khi function f(0) hoàn tất. Nhưng với Routines, các dòng code từ dòng 11 trở đi vẫn được thực thi cùng lúc với function f (0)
// Chỉ với từ khóa go, đoạn code dưới đây tạo ra tới 10 Goroutines func main() { for i := 0; i < 10; i++ { go f(i) } var input string fmt.Scanln(&input) }
Chốt hạ “The goroutines run simultaneously. – Goroutines chạy đồng thời”
3. Channels
Chỉ với từ khóa go, rõ ràng mà nói, tạo nhiều Goroutines không hề khó. Nhưng nếu các Goroutines muốn giao tiếp với nhau. Routines này chạy đồng bộ chờ kết quả routines khác?
Đấy, lúc đấy có ngay Channels.
Channels provide a way for two goroutines to communicate with each other and synchronize their execution
Channels cung cấp cách thức cho phép các goroutines giao tiếp với nhau và thực hiện đồng bộ hóa
Đối với channel, chiều gửi dữ liệu tuần theo chiều của mũi tên.
// Chỉ cần chú ý variable bên phải là bên gửi. ch <- v // Gửi giá trị v tới channels ch v := <-ch // Nhận giá trị từ channel ch, gán cho v.
Cũng giống như maps và slices, channels được khởi tạo ngay sao khi khai báo từ khóa chan.
ch := make(chan int)
Mặc định, việc gửi hay nhận ở goroutines này sẽ bị block cho tới khi goroutines khác thực hiện xong. Ví dụ dưới đây thực hiện tính toán đồng thời trên mảng s, cả hai routines sẽ thực hiện xong và cho kết quả cuối cùng.
package main import "fmt" func sum(s []int, c chan int) { sum := 0 sum += s[0] c <- sum // Gán tổng c cho sum } func main() { s := []int{7, 2, 8, -9, 4, 0} c := make(chan int) // Mảng s ở routines này là [-9, 4, 0] go sum(s[:len(s)/2], c) // Mảng s ở routines này là [7, 2, 8, -9] go sum(s[len(s)/2:], c) x, y := <-c, <-c // Nhận giá trị từ c fmt.Println(x, y, x+y) }
Channels c sau khi chạy sẽ in ra kết quả là:
// Thực hiện tuần tự sum 1 cho tới sum 2 -9 7 -2 Program exited.
Xong, bài viết này cho thấy một cái nhìn tổng quan nhất về Concurrency trong Golang. Nếu có bất cứ câu hỏi hoặc phản hồi gì, vui lòng comment bên dưới bài viết.
4. Tham khảo
Cảm ơn vì đã đọc bài. Happy coding!
Bài viết gốc được đăng tải tại kieblog.vn
Có thể bạn quan tâm:
- Channel trong Golang là gì? So sánh Callback function và mutex lock với channel
- Tìm hiểu về Graceful Shutdown, Graceful Shutdown trong Golang
- Một chút vui vẻ với Go
Xem thêm Việc làm Developer hấp dẫn trên TopDev