Semaphore เป็นกลไกสำหรับ Process/Thread Synchronization ใช้ควบคุมการเข้าถึง Shared Resource (Critical Section) เพื่อป้องกัน Race Condition ใน Linux ใช้ POSIX Semaphore Library (semaphore.h)
การคอมไพล์
gcc program_name.c -lpthread -lrt
-lpthread: Link pthread library
-lrt: Link real-time library (สำหรับ semaphore)
API หลัก
| ฟังก์ชัน | หน้าที่ |
sem_init(sem, pshared, value) | เริ่มต้น Semaphore (สำหรับ Thread ใน Process เดียว pshared=0) |
sem_wait(sem) | Lock/Wait: ลดค่า semaphore ถ้าเป็น 0 จะบล็อกจนกว่าจะ > 0 |
sem_post(sem) | Unlock/Signal: เพิ่มค่า semaphore และปลดบล็อก Thread ที่รอ |
sem_destroy(sem) | ทำลาย Semaphore เมื่อไม่ใช้แล้ว |
ตัวอย่าง: การทำงานแบบ Critical Section
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t mutex; // Global semaphore
void* thread(void* arg) {
sem_wait(&mutex); // เข้าสู่ Critical Section (Lock)
printf("\nEntered into the Critical Section..\n");
sleep(3); // จำลองงานใน Critical Section
printf("\nCompleted...\n");
sem_post(&mutex); // ออกจาก Critical Section (Unlock)
return NULL;
}
int main() {
sem_init(&mutex, 0, 1); // เริ่มต้นค่า = 1 (Binary Semaphore / Mutex)
pthread_t th1, th2;
pthread_create(&th1, NULL, thread, NULL);
sleep(2); // หน่วงเวลาเล็กน้อย
pthread_create(&th2, NULL, thread, NULL);
// รอ Thread ทั้งสองจบ
pthread_join(th1, NULL);
pthread_join(th2, NULL);
sem_destroy(&mutex); // ทำลาย Semaphore
return 0;
}
ผลลัพธ์
Entered into the Critical Section..
Completed...
Entered into the Critical Section..
Completed...
การทำงาน
- Thread แรกเข้ามา
sem_wait ได้เพราะค่าเริ่มต้น = 1 → กลายเป็น 0
- Thread ที่สองมา
sem_wait ต้องรอ (Block) เพราะค่า = 0
- Thread แรกทำงานเสร็จ
sem_post → ค่ากลายเป็น 1
- Thread ที่สองถูกปลดบล็อก เข้าทำงานต่อ
ประเภทของ Semaphore
- Binary Semaphore (Mutex): ค่า 0 หรือ 1 ใช้สำหรับ Mutual Exclusion
- Counting Semaphore: ค่า > 1 ใช้ควบคุม Resource จำนวนจำกัด (เช่น Connection Pool)
Named vs Unnamed Semaphore
- Unnamed (sem_init): ใช้ระหว่าง Thread ใน Process เดียวกัน
- Named (sem_open): ใช้ระหว่าง Process แยกกัน (IPC) คงอยู่ใน Kernel