Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

การใช้ POSIX Semaphores ในภาษา C สำหรับ Synchronization


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 หลัก

ตัวอย่าง: การทำงานแบบ 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...

การทำงาน

  1. Thread แรกเข้ามา sem_wait ได้เพราะค่าเริ่มต้น = 1 → กลายเป็น 0
  2. Thread ที่สองมา sem_wait ต้องรอ (Block) เพราะค่า = 0
  3. Thread แรกทำงานเสร็จ sem_post → ค่ากลายเป็น 1
  4. 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
ฟังก์ชันหน้าที่
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 เมื่อไม่ใช้แล้ว