A semaphore S is an integer(整数) variable that, apart from initialization, is accessed only through two standard atomic operations: P (proberen(测试) in Dutch) and V(verhogen(增加) in Dutch). 信号量 S 是一个整数变量,除了在初始化之外,信号量S被访问只能依靠两个原子操作 P 和 V
信号量的实现
伪代码:
1 2 3 4 5 6 7 8 9
P(s){ //测试信号量是否大于0,若大于0,执行自减操作 while(s<=0) do nothing; s--; }
使用信号量实现:当开始执行时假定BUFFER为空,那么 P 可以执行 C 不能执行,显然有两个控制流,故需要两个信号量来实现同步,因为 C 在程序开始时要等待,故将控制 C 的信号量初始值设为 0,当BUFFER满时,P将不能工作(进入忙式等待),等实现等待的只有 P操作 ,所以将控制 P 的信号量初始值设为 BUFFER 的大小,对 P 进程执行 P操作时会使得对应的信号量减1,之后要通知 C进程,使用 V(C进程的信号量)通知C进程,C进程在 P操作后会使信号量减1,之后要通知 P进程,V(P进程的信号量)
单缓冲解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Semaphore empty = 1; Semaphore full = 0;
Producer{ while(true){ //product; P(empty); //pull the product into buffer V(full); } }
Consumer{ while(true){ P(full); //pick product from buffer V(empty); } }
THE BOUNDED-BUFFER(有界缓冲区) PROBLEM
OUT:指向消费者使用的位置
IN: 指向生产者使用的位置
IN 与 OUT 形成了循环队列,IN 相当于队头(生产者生产后IN前移),OUT相对于队尾(消费者消费后OUT前移),保证 IN >= OUT 及生产者生产的大于消费者消费的
#define BUFSIZE 10 sem_t sem_empty; //生产者所使用的 sem_t sem_full; //消费者所使用的 sem_t mutex; int in = 0; //表示队列中生产者生产的内存 int out = 0; //表示队列中要消费的内容 int arr[BUFSIZE];
void *prodecer(void* arg)//生产者线程 { while (1) { sem_wait(&sem_empty);
sem_wait(&mutex); arr[in] = 1; printf("prodecer : %d\n", in); in = (in + 1) % BUFSIZE; sem_post(&mutex);
sem_post(&sem_full); sleep(1); } }
void *consumer(void* arg)//消费者线程 { printf("consumer -------------\n"); while (1) { sem_wait(&sem_full);