Linux 信号量的使用

信号量(semaphore)是一种用于控制多个线程对共享资源访问的同步机制。它可以用来限制同时访问某一资源的线程数量。信号量有两种类型:二元信号量(binary semaphore)和计数信号量(counting semaphore)。

什么时候使用信号量:

  1. 资源计数:当需要限制访问某些资源的线程数量时,例如限制同时访问数据库连接池的线程数。
  2. 解决生产者-消费者问题:控制生产者和消费者对缓冲区的访问,确保同步和互斥。
  3. 保护临界区:确保只有指定数量的线程能进入临界区,适用于多线程环境下的共享资源保护。

信号量使用示例:

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

#define NUM_THREADS 5
#define MAX_RESOURCES 3

sem_t semaphore;

void* worker(void* arg) {
    sem_wait(&semaphore);  // 等待信号量,进入临界区
    printf("Thread %ld is in critical section\n", (long)arg);
    sleep(1);  // 模拟临界区操作
    printf("Thread %ld is leaving critical section\n", (long)arg);
    sem_post(&semaphore);  // 释放信号量,离开临界区
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];
    sem_init(&semaphore, 0, MAX_RESOURCES);  // 初始化信号量,最大资源数为3
    for (long i = 0; i < NUM_THREADS; ++i) {
        pthread_create(&threads[i], NULL, worker, (void*)i);
    }
    for (int i = 0; i < NUM_THREADS; ++i) {
        pthread_join(threads[i], NULL);
    }
    sem_destroy(&semaphore);  // 销毁信号量
    return 0;
}

在这个示例中,信号量控制最多有3个线程能同时进入临界区(模拟资源访问)。信号量初始化时设定为3,表示最多3个线程可以同时进入临界区。线程进入临界区前调用 sem_wait,离开后调用 sem_post。信号量用来确保对共享资源的安全访问。