Những trường hợp cần biết khi dùng câu lệnh lựa chọn trong Golang

Trong ngôn ngữ Go, câu lệnh select giống như câu lệnh switch, nhưng trong câu lệnh select, câu lệnh case đề cập đến giao tiếp, tức là hoạt động gửi hoặc nhận trên kênh.

Lệnh select trong Golang

Cú pháp:

select{

case SendOrReceive1: // Lệnh
case SendOrReceive2: // Lệnh
case SendOrReceive3: // Lệnh
.......
default: // Lệnh

Trong bài viết này, chúng ta sẽ tìm hiểu cách sử dụng trường hợp mặc định để tránh rơi vào bế tắc - deadlock. Nhưng trước tiên, chúng ta sẽ tìm hiểu deadlock case khi dùng lệnh select của Golang là gì?

Những điều cần biết về deadlock case trong Golang

Deadlock: Khi bạn cố gắng đọc hoặc ghi dữ liệu từ kênh nhưng kênh không có giá trị. Vì vậy, nó chặn việc thực thi hiện tại của goroutine và chuyển quyền điều khiển cho các goroutine khác, nhưng nếu không có goroutine nào khác khả dụng hoặc các goroutine khác đang nghỉ do tình huống này, chương trình sẽ bị sập. Hiện tượng này được gọi là deadlock. Như được hiển thị trong ví dụ bên dưới:

Ví dụ:

// Chương trình Go minh hoạc
// cách deadlock phát sinh
package main 

// Hàm chính
func main() { 

	// Tạo một kênh
	// Deadlock phát sinh bởi
	// không có goroutine đang viết
	// vào kênh này, vì thế
	// lệnh select đã bị khóa mãi mãi
	c := make(chan int) 
	select { 
	case <-c: 
	} 
} 

Kết quả:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()

Để tránh tình huống này, chúng ta sử dụng trường hợp mặc định trong câu lệnh select. Hay nói cách khác, khi deadlock xảy ra trong chương trình, thì default case của câu lệnh select được thực thi để tránh deadlock. Như trong ví dụ dưới đây, chúng ta sử dụng trường hợp mặc định trong câu lệnh select để tránh deadlock.

Ví dụ:

// Chương trình Go minh họa cách giải quyết
// vấn đề deadlock bằng case mặc định
package main 

import "fmt"

// Hàm chính
func main() { 

	// Tạo 1 kênh
	c := make(chan int) 
	select { 
	case <-c: 
	default: 
		fmt.Println("!.. Default case..!") 
	} 
} 

Kết quả:

!.. Default case..!

Bạn cũng được phép sử dụng trường hợp mặc định khi câu lệnh select chỉ có kênh nil. Như được hiển thị trong ví dụ bên dưới, kênh c là nil, do đó trường hợp mặc định được thực thi nếu trường hợp mặc định ở đây không khả dụng, thì chương trình sẽ bị chặn mãi mãi và deadlock phát sinh.

Ví dụ:

// Chương trình Go minh họa
// chạy case mặc định
package main 

import "fmt"

// Hàm chính
func main() { 

	// Tạo một kênh
	var c chan int

	select { 
	case x1 := <-c: 
		fmt.Println("Value: ", x1) 
	default: 
		fmt.Println("Default case..!") 
	} 
} 

Kết quả:

Default case..!
Thứ Sáu, 14/03/2025 09:31
31 👨 327
Xác thực tài khoản!

Theo Nghị định 147/2024/ND-CP, bạn cần xác thực tài khoản trước khi sử dụng tính năng này. Chúng tôi sẽ gửi mã xác thực qua SMS hoặc Zalo tới số điện thoại mà bạn nhập dưới đây:

Số điện thoại chưa đúng định dạng!
Số điện thoại này đã được xác thực!
Bạn có thể dùng Sđt này đăng nhập tại đây!
Lỗi gửi SMS, liên hệ Admin
0 Bình luận
Sắp xếp theo
❖
    Chia sẻ
    Chia sẻ FacebookChia sẻ Twitter
    Đóng