Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Sử dụng POSIX Semaphore trong C

Semaphore (tín hiệu) là cơ chế đồng bộ hóa tiến trình/luồng (thread) kinh điển. Thư viện POSIX semaphore (semaphore.h) cung cấp semaphore không tên (dùng cho thread trong cùng tiến trình) và semaphore có tên (dùng cho IPC - giao tiếp giữa các tiến trình).

Các hàm chính

HàmMô tả
sem_init(sem_t *sem, int pshared, unsigned int value)Khởi tạo semaphore không tên. pshared=0 cho thread, pshared!=0 cho tiến trình.
sem_wait(sem_t *sem)Giảm semaphore (khóa/chờ). Nếu giá trị = 0 thì block cho đến khi > 0.
sem_post(sem_t *sem)Tăng semaphore (mở khóa). Đánh thức một thread đang chờ (nếu có).
sem_destroy(sem_t *sem)Hủy semaphore, giải phóng tài nguyên.
sem_open / sem_close / sem_unlinkDành cho semaphore có tên (IPC).

Biên dịch

Cần link thư viện pthread và rt:

gcc ten_file.c -lpthread -lrt -o ten_chuong_trinh

Ví dụ: Đồng bộ hóa 2 thread truy cập Critical Section

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

sem_t mutex; // Semaphore toàn cục

void* thread_func(void* arg) {
    sem_wait(&mutex);           // Vào Critical Section (khóa)
    printf("\nThread %lu: Dang trong Critical Section...\n", (unsigned long)pthread_self());
    sleep(3);                   // Giả lập công việc
    printf("Thread %lu: Hoan thanh, roi Critical Section.\n", (unsigned long)pthread_self());
    sem_post(&mutex);           // Ra khỏi Critical Section (mở khóa)
    return NULL;
}

int main() {
    sem_init(&mutex, 0, 1);     // Khởi tạo mutex = 1 (binary semaphore)

    pthread_t th1, th2;
    pthread_create(&th1, NULL, thread_func, NULL);
    sleep(1); // Tạo độ trễ nhỏ để thấy rõ thứ tự
    pthread_create(&th2, NULL, thread_func, NULL);

    pthread_join(th1, NULL);    // Đợi thread 1 kết thúc
    pthread_join(th2, NULL);    // Đợi thread 2 kết thúc

    sem_destroy(&mutex);        // Dọn dẹp
    return 0;
}

Kết quả chạy

Thread 12345: Dang trong Critical Section...
Thread 12345: Hoan thanh, roi Critical Section.
Thread 12346: Dang trong Critical Section...
Thread 12346: Hoan thanh, roi Critical Section.

Giải thích: Semaphore mutex được khởi tạo giá trị 1. Thread đầu tiên gọi sem_wait thành công (giá trị thành 0), thread thứ hai sẽ bị block tại sem_wait cho đến khi thread đầu gọi sem_post (giá trị thành 1). Điều này đảm bảo chỉ có một thread tại một thời điểm truy cập Critical Section.

Lưu ý

  • Luôn kiểm tra giá trị trả về của các hàm semaphore (trả về -1 khi lỗi, đặt errno).
  • Semaphore không tên chỉ dùng cho thread cùng tiến trình (hoặc tiến trình con sau fork với pshared != 0).
  • Đối với IPC giữa tiến trình không liên quan, dùng sem_open với tên (ví dụ: /my_sem).