1. Concurrency là gì?

Concurrency là khả năng tổ chức nhiều công việc để chúng có thể tiến triển xen kẽ hoặc đồng thời trong cùng một khoảng thời gian. Thay vì phải thực hiện tất cả công việc theo một trình tự duy nhất, chương trình có thể chuyển đổi giữa nhiều công việc đang chờ hoặc đang xử lý.

Ví dụ, một backend cần xử lý ba request cùng lúc. Nếu chương trình chỉ xử lý tuần tự, request thứ hai có thể phải chờ request thứ nhất hoàn thành, ngay cả khi request thứ nhất đang chờ database trả kết quả. Với concurrency, server có thể tiếp tục xử lý những request khác trong thời gian chờ đó.

Go hỗ trợ concurrency ngay trong ngôn ngữ thông qua goroutine, channel và các công cụ đồng bộ. Những cơ chế này giúp tổ chức chương trình có nhiều công việc mà không cần developer tự quản lý từng OS thread.

2. Phân biệt Concurrency và Parallelism

Hai khái niệm này thường đi cùng nhau nhưng không hoàn toàn giống nhau.

Concurrency nói về cách thiết kế và tổ chức nhiều công việc có thể tiến triển độc lập. Parallelism là việc thực sự thực thi nhiều công việc cùng một thời điểm, thường thông qua nhiều CPU core.

Ví dụ, một ứng dụng tải dữ liệu từ nhiều API có thể gửi request đến API A, B và C mà không cần đợi từng request hoàn thành rồi mới gửi request tiếp theo. Đây là một cách tận dụng concurrency, đặc biệt hữu ích khi thời gian xử lý chủ yếu nằm ở việc chờ network.

Go hỗ trợ cả hai. Runtime của Go quản lý và lập lịch goroutine trên các OS thread; khi cấu hình và tài nguyên cho phép, nhiều goroutine có thể thực sự chạy song song trên các CPU core.

3. Goroutine là gì?

Goroutine là một đơn vị thực thi nhẹ do Go runtime quản lý. Nó cho phép một function chạy đồng thời với phần code đã khởi chạy nó.

Trong Go, chỉ cần thêm từ khóa go trước một lời gọi function là có thể khởi chạy function đó trong một goroutine mới.

package main

import (
    "fmt"
    "time"
)

func sayHello() {
    fmt.Println("Hello from goroutine")
}

func main() {
    go sayHello()

    time.Sleep(time.Second)
    fmt.Println("Main finished")
}

Ở đây, go sayHello() khởi chạy sayHello() trong một goroutine riêng. Function main() tiếp tục thực thi mà không cần chờ sayHello() kết thúc ngay tại dòng đó.

Một đặc điểm quan trọng là goroutine không đồng nghĩa với OS thread. Go runtime có thể lập lịch nhiều goroutine trên một số lượng OS thread phù hợp. Điều này giúp tạo và quản lý nhiều tác vụ đồng thời thuận tiện hơn so với việc tự quản lý thread ở mức hệ điều hành.

Goroutine có tự chạy đến khi hoàn thành không?

Goroutine có thể tiếp tục chạy sau khi function khởi chạy nó đã trả về. Tuy nhiên, goroutine không được bảo đảm sẽ hoàn thành trước khi chương trình kết thúc.

Ví dụ:

func main() {
    go func() {
        fmt.Println("Background task")
    }()
}

Khi main() kết thúc, chương trình có thể kết thúc luôn trước khi goroutine kịp in nội dung. Runtime không tự động chờ tất cả goroutine hoàn thành.

4. Tổng kết

Goroutine & Concurrency là phần cốt lõi của Go khi xây dựng các ứng dụng có nhiều công việc tiến triển đồng thời.

Goroutine cho phép chạy function độc lập; sync.WaitGroup giúp chờ các công việc hoàn thành; channel truyền dữ liệu và phối hợp giữa các goroutine; select giúp chờ nhiều hoạt động; còn mutex và các primitive trong package sync bảo vệ dữ liệu dùng chung.

Bên cạnh những cơ chế này, phải hiểu rõ race condition, deadlock và goroutine leak. Context giữ vai trò quan trọng trong việc truyền deadline và tín hiệu cancellation, đặc biệt với các tác vụ thuộc một request backend. Worker Pool là một pattern hữu ích khi cần giới hạn số lượng công việc chạy đồng thời.

Bài viết khác

Go Channels & Go Context

1. Go Channels & Go Context là gì? Trong Go, goroutine cho phép chương trình chạy nhiều công việc đồng thời. Tuy nhiên, khi có nhiều goroutine cùng hoạt động, chúng cần một cách để trao đổi kết quả, phối hợp thời điểm thực thi và dừng công việc khi không còn cần thiết.  Đây […]

Go Fundamentals

1. Go là gì? Go (Golang) là ngôn ngữ lập trình go thường được sử dụng trong backend, REST API, hệ thống mạng, công cụ dòng lệnh, cloud infrastructure và các dịch vụ chạy đồng thời. Go là ngôn ngữ biên dịch và có hệ thống kiểu dữ liệu tĩnh (statically typed). Điều này có […]

Laravel Routing & Controllers

1. Laravel Routing & Controllers là gì? Khi xây dựng backend bằng Laravel, client gửi HTTP request đến server để thực hiện một thao tác như lấy danh sách user, xem chi tiết sản phẩm hoặc tạo đơn hàng. Laravel cần xác định request đó sẽ được xử lý ở đâu và logic xử lý […]

Series 2 — Frontend Fundamentals: Responsive Web Design – Bootstrap

Series 2 — Frontend Fundamentals   HTML → Sematic HTML → Forms & Validation → CSS  Flexbox & Grid → Responsive Web Design → Bootstrap   Bài 6. Responsive Web Design – Giao diện đa thiết bị 1. Responsive Web Design là gì? Khi xây dựng một website, chúng ta không thể giả định rằng […]

HTTP & HTTPS

Giao thức HTTP và HTTPS là gì? 1. HTTP là gì? HTTP (Hypertext Transfer Protocol) là giao thức truyền tải siêu văn bản, được sử dụng để trao đổi dữ liệu giữa client (máy khách) và server (máy chủ). Ban đầu, HTTP được phát triển để trao đổi các tài liệu trên Web. Ngày nay, […]

Series 2 — Frontend Fundamentals: CSS — Flexbox-Grid

Series 2 — Frontend Fundamentals   HTML → Sematic HTML → Forms & Validation → CSS  Flexbox & Grid → Responsive Web Design → Bootstrap   Bài 4. CSS Fundamentals – CSS là gì?   CSS Fundamentals – CSS là gì và hoạt động như thế nào? Ở những bài trước, chúng ta đã tìm […]

Leave a Reply

Your email address will not be published. Required fields are marked *