- vừa được xem lúc

So sánh sự khác biệt giữa Binary Semaphore và Counting Semaphore

0 0 2

Người đăng: delinux

Theo Viblo Asia

Trong các hệ điều hành thời gian thực (RTOS), việc đồng bộ và quản lý truy cập tài nguyên dùng chung là cực kỳ quan trọng để đảm bảo tính ổn định và an toàn của hệ thống. Hai trong số các công cụ phổ biến được sử dụng để giải quyết vấn đề này là Binary SemaphoreCounting Semaphore.

Dù có tên gọi tương đồng và được dùng trong những tình huống khá giống nhau, hai loại Semaphore này thực chất phục vụ các mục đích khác nhau và có hành vi khác biệt rõ rệt.


1. Khái Niệm Cơ Bản

1.1 Binary Semaphore (Semaphore nhị phân)

Binary Semaphore chỉ có hai trạng thái: 01, tương đương với locked (đang giữ)unlocked (sẵn sàng). Semaphore loại này thường được sử dụng để:

  • Đồng bộ hóa giữa taskISR (Interrupt Service Routine)
  • Báo hiệu giữa các task (signal)
  • Bảo vệ tài nguyên chỉ có một luồng truy cập tại một thời điểm

1.2 Counting Semaphore (Semaphore đếm)

Counting Semaphore có thể giữ giá trị lớn hơn 1, cho phép nhiều task có thể "take" semaphore nếu còn chỗ trống. Nó thường được dùng để:

  • Quản lý số lượng tài nguyên hạn chế (ví dụ: 3 cổng UART)
  • Đồng bộ hóa với nhiều nguồn tín hiệu
  • Quản lý hàng đợi hoặc buffer vòng

2. Hoạt Động Của Semaphore

2.1 Sơ đồ hoạt động của Binary Semaphore

image.png

2.2 Sơ đồ hoạt động của Counting Semaphore

image.png


3. So Sánh Chi Tiết Binary vs Counting Semaphore

Tiêu chí Binary Semaphore Counting Semaphore
Giá trị tối đa 1 Tùy ý (do lập trình viên khai báo)
Mục đích chính Đồng bộ hóa Quản lý số lượng tài nguyên
Dùng để bảo vệ tài nguyên Có thể, nhưng không tối ưu như mutex Có thể, nhưng không phải mục tiêu chính
Có thể bị “give” nhiều lần Không (chỉ giữ giá trị là 1) Có thể tăng giá trị liên tục
Giao tiếp giữa Task và ISR Rất phù hợp Không phổ biến, nhưng có thể
Giải phóng bởi nhiều task Không khuyến nghị Có thể
Hành vi như tín hiệu Tốt Tốt, nếu cần đếm số lượng tín hiệu
Cấu trúc bên trong Dựa trên queue có 1 phần tử Dựa trên queue có nhiều phần tử

4. Ví Dụ Minh Họa

4.1 Ví dụ dùng Binary Semaphore để đồng bộ ISR và Task

SemaphoreHandle_t xBinarySemaphore; void ISR_Handler(void)
{ BaseType_t xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} void TaskWaitForISR(void *pvParameters)
{ for (;;) { if (xSemaphoreTake(xBinarySemaphore, portMAX_DELAY)) { printf("Interrupt received!\n"); } }
}

Diễn giải:

  • xBinarySemaphore là semaphore nhị phân, chỉ mang giá trị 0 hoặc 1.
  • ISR sẽ "give" semaphore để báo cho task biết rằng ngắt đã xảy ra.
  • Task đang xSemaphoreTake sẽ bị block cho đến khi ISR gọi xSemaphoreGiveFromISR.

4.2 Ví dụ dùng Counting Semaphore để quản lý 3 tài nguyên

SemaphoreHandle_t xCountingSemaphore; void ResourceTask(void *pvParameters)
{ while (1) { if (xSemaphoreTake(xCountingSemaphore, portMAX_DELAY)) { // Sử dụng tài nguyên printf("Task %d dùng tài nguyên\n", (int)pvParameters); vTaskDelay(pdMS_TO_TICKS(1000)); // Trả lại tài nguyên xSemaphoreGive(xCountingSemaphore); } }
} void main()
{ xCountingSemaphore = xSemaphoreCreateCounting(3, 3); // 3 tài nguyên xTaskCreate(ResourceTask, "T1", 1000, (void *)1, 1, NULL); xTaskCreate(ResourceTask, "T2", 1000, (void *)2, 1, NULL); xTaskCreate(ResourceTask, "T3", 1000, (void *)3, 1, NULL); xTaskCreate(ResourceTask, "T4", 1000, (void *)4, 1, NULL);
}

Diễn giải:

  • Semaphore khởi tạo với count = 3, nghĩa là có 3 tài nguyên.
  • 4 task cạnh tranh sử dụng, chỉ 3 task chạy được cùng lúc, task còn lại phải đợi.
  • Sau khi sử dụng xong, task sẽ give lại semaphore.

5. Ưu và Nhược Điểm

5.1 Binary Semaphore

Ưu điểm:

  • Đơn giản, dễ sử dụng
  • Hiệu quả khi đồng bộ ISR với task
  • Không cần đếm hay kiểm tra giá trị

Nhược điểm:

  • Không dùng được cho nhiều tài nguyên
  • Không lưu trữ số lượng tín hiệu nếu nhiều hơn 1 ISR xảy ra trước khi task xử lý
  • Dễ bị “mất tín hiệu” nếu task chưa take mà ISR gọi nhiều lần liên tiếp

5.2 Counting Semaphore

Ưu điểm:

  • Quản lý nhiều tài nguyên rất tốt
  • Có khả năng tích lũy tín hiệu (giữ số lượng)
  • Có thể linh hoạt dùng trong nhiều tình huống đồng bộ phức tạp

Nhược điểm:

  • Phức tạp hơn binary
  • Có thể gây lỗi nếu không kiểm soát chính xác việc takegive
  • Không thích hợp nếu chỉ cần đồng bộ đơn giản hoặc giao tiếp ISR-task

6. Khi Nào Dùng Binary, Khi Nào Dùng Counting?

Trường hợp Dạng Semaphore phù hợp
ISR báo hiệu cho Task Binary Semaphore
Task cần sử dụng tài nguyên độc quyền Mutex (ưu tiên hơn binary)
Có nhiều tài nguyên giống nhau (ví dụ 5 UART) Counting Semaphore
Có nhiều tín hiệu đến liên tiếp Counting Semaphore
Cần “bật đèn xanh” cho task bắt đầu Binary Semaphore

7. Kết Luận

Binary Semaphore và Counting Semaphore đều là những công cụ mạnh mẽ cho việc đồng bộ hóa trong RTOS như FreeRTOS. Việc lựa chọn đúng loại semaphore không chỉ giúp hệ thống hoạt động ổn định mà còn tránh được các lỗi tiềm ẩn như race condition, deadlock, hoặc dropped signals.

Tổng kết:

  • Binary Semaphore: Sử dụng khi cần đồng bộ một sự kiện duy nhất giữa 2 thành phần (ví dụ ISR và Task).
  • Counting Semaphore: Dùng khi cần quản lý số lượng nhiều tài nguyên hoặc nhiều tín hiệu xảy ra liên tiếp.

Bình luận

Bài viết tương tự

- vừa được xem lúc

[Golang] Channel trong golang và use case - part III

Mở đầu. . Tiếp tục series, hôm nay là một buổi chia sẽ của tôi về use case của channel trong GO. Let's go, guys.

0 0 30

- vừa được xem lúc

Giới thiệu về Semaphore trong RTOS

1. Giới thiệu nhanh.

0 0 8

- vừa được xem lúc

Cơ bản về WatchDog Timer trong hệ thống nhúng (Embedded System)

Khái Niệm. Trong hệ thống nhúng, a WatchDog Timer (Bộ đếm thời gian giám sát) là một thành phần hoặc tính năng của phần cứng được thiết kế để giám sát hoạt động của hệ thống và thực hiện hành động khắ

0 0 20

- vừa được xem lúc

Khái niệm về Multitasking trên vi điều khiển!

Giới thiệu nhanh. Vi điều khiển (microcontroller) là trái tim của rất nhiều thiết bị nhúng như máy đo nhiệt độ, đồng hồ thông minh, hệ thống cảnh báo, robot.

0 0 17

- vừa được xem lúc

Vấn đề về quản lý bộ nhớ trên vi điều khiển khi sử dụng FreeRTOS - Phần 1

Giới thiệu nhanh. Ở bài trước, mình đã cùng bạn tìm hiểu về task – một trong những khái niệm quan trọng nhất khi làm việc với hệ điều hành thời gian thực (RTOS) trên vi điều khiển.

0 0 10

- vừa được xem lúc

Quản lý ưu tiên và lập lịch tác vụ hiệu quả trong FreeRTOS

Giới thiệu. Như đã giới thiệu từ những bài trước, hệ điều hành thời gian thực (RTOS) như FreeRTOS cho phép bạn thiết kế các ứng dụng nhúng có khả năng thực hiện nhiều nhiệm vụ (task) đồng thời.

0 0 16