信号量(semaphore)是一种常被用于多线程或多进程场景中的同步机制,用于保证多线程或多进程对共享数据的读/写操作是顺序的。
信号量的本质上是一个计数器,维护着一个 Value:
二元信号量(Binary Semaphore),即:计数器维护的 Value 只有 0 和 1 着两种可能,以此来实现互斥,所以也称为互斥信号量。
需要注意的是,二元信号量只能用于实现互斥,无法实现同步。如果需要实现线程间的同步,可以使用计数信号量(Counting Semaphore)。
另外,二元信号量的使用应尽量避免死锁问题的发生,即:避免出现多个线程相互等待的情况。
C 语言可以使用 semaphore.h 库来使用二元信号量。
函数作用:用于创建并初始化一个二元信号量实体。
函数原型:
#include int sem_init(sem_t *sem, int pshared, unsigned int value);
函数作用:
函数原型:
#include int sem_wait(sem_t *sem);
函数作用:当线程完成了共享数据的访问后,应该使用 sem_post() 释放二元信号量,即:将 Value 变 1,让其他线程可以获取。
函数原型:
#include int sem_post(sem_t *sem);
#include
#include
#include
#include #define NUM_THREADS 2sem_t mutex;void* thread_func(void* arg) {int tid = *(int*) arg;printf("Thread %d waiting...\n", tid);/* 用一个互斥信号量来保护一个临界区。 */sem_wait(&mutex); // 每个线程都先等待信号量变为正,然后进入临界区进行操作。printf("Thread %d entered critical section.\n", tid);sleep(1);printf("Thread %d exiting critical section.\n", tid);sem_post(&mutex); // 离开临界区并释放信号量。pthread_exit(NULL);
}int main() {pthread_t threads[NUM_THREADS];int thread_args[NUM_THREADS];int i;// Initialize the semaphoresem_init(&mutex, 0, 1);// Create the threadsfor (i = 0; i < NUM_THREADS; i++) {thread_args[i] = i;pthread_create(&threads[i], NULL, thread_func, &thread_args[i]);}// Wait for the threads to finishfor (i = 0; i < NUM_THREADS; i++) {pthread_join(threads[i], NULL);}// Destroy the semaphoresem_destroy(&mutex);return 0;
}