互斥与同步
互斥和同步是两个紧密相关而又容易混淆的概念。
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源,如“第一类读写者模型”。
生产者-消费者模型
生产者-消费者模型是指:
1. 生产者进行生产将物品放入仓库,同一时间只能有一个生产者将物品放入仓库,如果仓库满,生产者等待。
2. 消费者从仓库中取出物品,同一时间只能有一个消费者取出物品,如果仓库空,消费者等待;
3. 生产者将物品放入仓库时消费者不能同时取;
4. 消费者取物品时生产者不能放入物品;
总之,就是生产者群体或消费者群体内部是互斥的,两个群体之间是同步的。
当只有一个生产者、消费者时,由于同一群体内部不需要互斥,所以只需在群体之间实 现同步即可。
代码:
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<semaphore.h>
#define N 2 //生产者和消费者个数
#define M 10 //缓冲区大小
int in=0;//生产者写的位置
int out=0;//消费者取的位置
int buf[M]={0};
sem_t empty_sem;//空信号量
sem_t full_sem;//满信号量
pthread_mutex_t mutex;//互斥的
int product_id=0;
int purchase_id=0;
void print(){
int i;
for( i=0;i<M;++i){
printf("%d ",buf[i]);
}
printf("\n");
}
void* product(){
int id=++product_id;
while(1){
sleep(1);
sem_wait(&empty_sem);
pthread_mutex_lock(&mutex);
in =in%M;
printf("product_id:%d in %d like:",id,in);
buf[in]=1;
print();
++in;
pthread_mutex_unlock(&mutex);
sem_post(&full_sem);
}
}
void* purchase(){
int id=++purchase_id;
while(1){
sleep(1);
sem_wait(&full_sem);
pthread_mutex_lock(&mutex);
out=out%M;
printf("purchse %d in % d like:",id,out);
buf[out]=0;
print();
++out;
pthread_mutex_unlock(&mutex);
sem_post(&empty_sem);
}
}
int main(){
pthread_t id[N];
pthread_t id2[N];
int i;
int ret[N];
int ini1=sem_init(&empty_sem,0,M);
int ini2=sem_init(&full_sem,0,0);
int ini3=pthread_mutex_init(&mutex,NULL);
for(i=0;i<N;++i){
ret[i]=pthread_create(&id[i],NULL,product,NULL);
}
for(i=0;i<N;++i){
ret[i]=pthread_create(&id2[i],NULL,purchase,NULL);
}
for(i=0;i<N;++i){
pthread_join(id[i],NULL);
pthread_join(id2[i],NULL);
}
return 0;
}