多线程同步之信号量
信号量是什么?简单来说,信号量就是一个计数值,假设记为S。S > 0时,表示当前可用资源的数目;S < 0时,其绝对值表示等待使用该资源的进程个数。信号量可作为一种同步手段控制多个进程对资源的访问。
可以通过PV操作改变信号量的值。
P操作:
S = S -1; if S >= 0 continue; else blocked;
V操作:
S = S + 1; if S > 0 continue; else wakeup a blocked process;
信号量的经典应用当属“生产者-消费者”问题。生产者-消费者问题(producer-consumer problem)又被称为有限缓冲问题(bounded-buffer problem)。存在一个固定大小的缓冲区,生产者进程向缓冲区中存放数据,消费者进程从缓冲区中取走数据。但是缓冲区满时,生产者不能向其中存放数据;缓冲区空时,消费者不能从缓冲区中取走数据。信号量是这一问题的常见解决方案。
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define bufferSize 5 #define N 10 //number of producer int buffer[bufferSize]; sem_t mutex; sem_t empty; sem_t full; int i = 0; int j = 0; void* produce(void *arg) { while (1) { sem_wait(&empty); sem_wait(&mutex); buffer[i] = 10 + rand() %90; printf("Producer %d write Buffer[%d]: %d\n", arg, i, buffer[i]); i = (i+1) % bufferSize; sem_post(&mutex); sem_post(&full); } } void* consume(void *arg) { while (1) { sem_wait(&full); sem_wait(&mutex); printf("Consumer %d read Buffer[%d]: %d\n", arg, j, buffer[j]); j = (j+1) % bufferSize; sem_post(&mutex); sem_post(&empty);
} } int main() { sem_init(&mutex, 0, 1); sem_init(&empty, 0, bufferSize); sem_init(&full, 0, 0); pthread_t producers[N]; pthread_t consumers[N]; int i; for (i = 0; i < N; ++i) { pthread_create(&producers[i], NULL, produce, (void*)i); pthread_create(&consumers[i], NULL, consume, (void*)i); } sleep(1); sem_destroy(&mutex); sem_destroy(&empty); sem_destroy(&full); return 0; }
用到的函数有:
int sem_init(sem_t *sem, int pshared, unsigned int value); int sem_wait(sem_t *sem); int sem_post(sem_t *sem); int sem_destroy(sem_t *sem);
REFERENCE: