0
0
Lập trình
Admin Team
Admin Teamtechmely

Khám Phá Lập Trình Concurrent trong Golang: Tăng Tốc Hiệu Suất Ứng Dụng

Đăng vào 3 ngày trước

• 4 phút đọc

Giới Thiệu Về Lập Trình Concurrent Trong Golang

Concurrency (đồng thời) là một trong những yếu tố cốt lõi trong lập trình ngày nay, đặc biệt trong việc phát triển các ứng dụng hiệu suất cao. Golang, được phát triển bởi Google, nổi bật với khả năng xử lý đồng thời một cách hiệu quả. Trong bài viết này, chúng ta sẽ đi sâu vào lập trình concurrency trong Golang và tìm hiểu các khái niệm cơ bản cùng các phương pháp để xây dựng các ứng dụng mạnh mẽ.

Concurrency Là Gì?

Concurrency là khả năng thực hiện nhiều tác vụ cùng một lúc bằng cách chia nhỏ chúng thành các tác vụ nhỏ hơn. Dù rằng mọi tác vụ không phải lúc nào cũng chạy đồng thời, khả năng chuyển đổi nhanh giữa các tác vụ giúp cải thiện hiệu suất của ứng dụng. Trong Golang, mỗi tác vụ được coi là một Goroutine.

Goroutines Là Gì?

Goroutines là các luồng thực thi nhẹ (lightweight execution threads) mà Golang cung cấp. Chúng được quản lý bởi Go runtime, giúp tiết kiệm tài nguyên bộ nhớ và cho phép thực hiện hàng nghìn tác vụ đồng thời mà không gây ra sự phức tạp.

  • Mỗi ứng dụng Golang có một Goroutine chính, được gọi là main Goroutine. Nếu main Goroutine dừng, tất cả Goroutines khác cũng sẽ ngừng hoạt động.

Để khởi tạo một Goroutine, bạn chỉ cần thêm từ khóa go trước lời gọi hàm:

Copy
func quan() {
    // code
}

go quan()

Ví Dụ Cơ Bản Về Goroutines

Hãy xem một ví dụ đơn giản sau:

Copy
package main
import (
    "fmt"
)

func showName(s string) {
    for i := 0; i < 3; i++ {
        fmt.Println(s)
    }
}

func main() {
    go showName("Quân")
    go showName("Troy")
}

Khi chạy chương trình trên, bạn có thể thấy rằng không có đầu ra nào được hiển thị. Điều này xảy ra do main Goroutine kết thúc trước khi hai Goroutines kia hoàn thành nhiệm vụ.

Sử Dụng time.Sleep Để Đợi Các Goroutines

Để đảm bảo rằng tất cả các Goroutines hoàn thành trước khi kết thúc ứng dụng, bạn có thể sử dụng time.Sleep để tạm dừng chương trình:

Copy
package main
import (
    "fmt"
    "time"
)

func showName(s string) {
    for i := 0; i < 3; i++ {
        fmt.Println(s)
    }
}

func main() {
    go showName("Quân")
    go showName("Troy")
    time.Sleep(1 * time.Second)
}

Kết quả sẽ như mong đợi:

Copy
Troy
Troy
Troy
Quân
Quân
Quân

Quản Lý Goroutines Với WaitGroup

Thay vì dùng time.Sleep, chúng ta có thể dùng WaitGroup để quản lý khi nào Goroutines hoàn thành:

Copy
package main
import (
    "fmt"
    "sync"
)

func sayName(s string, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 3; i++ {
        fmt.Println(s)
    }
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    go sayName("Quân", &wg)
    go sayName("Troy", &wg)
    wg.Wait()
    fmt.Println("Ứng dụng kết thúc")
}

Tìm Hiểu Về Channel

Trong Golang, Channel cho phép Goroutines giao tiếp với nhau. Bạn có thể tạo Channel bằng cách sử dụng hàm make:

Copy
ch := make(chan string)

Ví dụ sau cho thấy cách gửi và nhận dữ liệu qua Channel:

Copy
package main
import "fmt"

func sayName(s string, ch chan string) {
    result := ""
    for i := 0; i < 3; i++ {
        result += s + " là tên của tôi, "
    }
    ch <- result
}

func main() {
    ch := make(chan string)
    go sayName("Quân", ch)
    fmt.Println(<-ch)
    fmt.Println("Ứng dụng kết thúc")
}

Hiểu Về Deadlock

Deadlock là tình huống mà một hoặc nhiều Goroutines đang chờ mà không bao giờ kết thúc. Hãy xem ví dụ sau:

Copy
func main() {
    ch := make(chan int)
    ch <- 1 // Dòng này sẽ gây ra deadlock
}

Khi chương trình không có goroutine nào khác nhận dữ liệu từ Channel, tình huống Deadlock sẽ xảy ra.

Buffered Channel

Buffered Channel cho phép chứa một số giá trị nhất định mà không cần phải nhận ngay lập tức. Bạn có thể tạo một Buffered Channel như sau:

Copy
ch := make(chan int, 3)

Khi bạn gửi giá trị vào channel, nếu không vướt quá kích thước của buffer, main Goroutine sẽ không bị chặn.

Kết Luận

Bài viết đã giới thiệu về lập trình concurrency trong Golang và giải thích các khái niệm cơ bản như Goroutines, WaitGroup, và Channel. Các ưu điểm của việc sử dụng concurrency giúp xây dựng các ứng dụng mạnh mẽ và linh hoạt, tối ưu hóa tài nguyên sẵn có. Hãy tiếp tục khám phá và thực hành với Goroutines để nâng cao kỹ năng lập trình của bạn trong Golang. Nếu bạn có bất kỳ câu hỏi nào, đừng ngần ngại để lại ý kiến bên dưới nhé!

Tài Liệu Tham Khảo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào