//
//author : superfish
//date : 2015/11/18
//name : buffer.h
//
#include
#ifndef _BUFFER_H
#define _BUFFER_H
#define BUFFER_SIZE 5
#define TRUE 1
#define FALSE 0
typedef struct
{ //定义缓冲区结构
int buffer[BUFFER_SIZE]; //缓冲区
int read_i; //读位置
int write_i; //写位置
int count; //需要处理的元素个数
int written_c; //已经写入的元素个数
int read_c; //已经读取的元素个数
}BUFFER;
typedef struct
{ //定义线程函数参数的结构
BUFFER *pBUFFER;
sem_t mutex; //互斥锁
sem_t empty, full; //标准记数信号量
}PARAM;
//bufferfunc.c
BUFFER * init_buffer(int count);
int inserti(int item, BUFFER * pBUFFER, sem_t mutex, sem_t empty, sem_t full);
int removei(int item, BUFFER * pBUFFER, sem_t mutex, sem_t empty, sem_t full);
//procon.c
unsigned int getrand(unsigned int n);
int producer(void * param);
int consumer(void * param);
#endif
//
//author : superfish
//date : 2015/11/18
//name : bufferfunc.c
//
#include
#include
#include "buffer.h"
BUFFER * init_buffer(int count)
{ //初始化BUFFER
BUFFER * pBUFFER;
pBUFFER = (BUFFER *)malloc(sizeof(BUFFER));
memset(pBUFFER->buffer, 0, BUFFER_SIZE);
pBUFFER->read_i = 0;
pBUFFER->write_i = 0;
pBUFFER->read_c = 0;
pBUFFER->written_c = 0;
pBUFFER->count = count;
return pBUFFER;
}
int inserti(int item, BUFFER * pBUFFER, sem_t mutex, sem_t empty, sem_t full)
{ //把一个元素放入缓冲区
int i = pBUFFER->write_i;
while(TRUE){
sem_wait(&empty);
sem_wait(&mutex);
//临界区
if(pBUFFER->written_c == pBUFFER->count){ //任务已经完成了
sem_post(&mutex);
return 0;
}else{
buffer[i%BUFFER_SIZE] = item;
pBUFFER->write_i = (i+1)%BUFFER_SIZE;
(pBUFFER->written_c)++;
sem_post(&mutex);
sem_post(&full);
return 1;
}
}
}
int removei(int item, BUFFER * pBUFFER, sem_t mutex, sem_t empty, sem_t full)
{ //从缓冲区取出一个元素
int i = pBUFFER->read_i;
while(TRUE){
sem_wait(&full);
sem_wait(&mutex);
//临界区
if(pBUFFER->read_c == pBUFFER->count){ //任务已经完成了
sem_post(&mutex);
return 0;
}else{
item = buffer[i%BUFFER_SIZE];
pBUFFER->read_i = (i+1)%BUFFER_SIZE
(pBUFFER->read_c)++;
sem_post(&mutex);
sem_post(&empty);
return item;
}
}
}
//
//author : superfish
//date : 2015/11/18
//name : procon.c
//
#include
#include
#include
#include "buffer.h"
extern param;
unsigned int getrand(unsigned int n)
{ //生成一个1~n的随机整数
srand(time(0));
return rand()%(n+1);
}
int producer(void * p)
{ //生产者
int item;
int id;
BUFFER *pBUFFER = param->pBUFFER;
sem_t mutex = param->mutex;
sem_t empty = param->empty;
sem_t full = param->full;
item = getrand(100);
id = pthread_self(); //当前线程号
sleep(getrand(3)); //生产者随机休息1~3秒
while(TRUE){
if(!inserti(item, pBUFFER, mutex, empty, full)){
break;
}else{
printf("Thread %d product a %d\n", id, item);
}
}
return 0;
}
int consumer(void * p)
{ //消费者
pthread id;
int item;
BUFFER *pBUFFER = param->pBUFFER;
sem_t mutex = param->mutex;
sem_t empty = param->empty;
sem_t full = param->full;
id = pthread_self(); //当前线程号
sleep(getrand(5)); //消费者随机休息1~5秒
while(TRUE){
item = removei(item, pBUFFER, mutex, empty, full);
if(!item){
break;
}
else{
printf("Thread %d consume a %d\n", id, item);
}
}
return 0;
}
//
//author : superfish
//date : 2015/11/18
//name : main.c
//
#include
#include
#include
#include
#include "buffer.h"
PARAM *param; //全局参数结构
int main(int argc, char ** argv)
{ //主函数
int i;
int count; //任务量
int pnun, cnum; //生产者、消费者线程数
BUFFER *pBUFFER; //缓冲区结构
pthread *ptid; //生产者线程id数组
pthread *ctid; //消费者线程id数组
pthread_attr_t attr; //线程属性
//错误处理
if(argc != 4){
fprintf(stderr, "Param error!\n");
return -1;
}
if(int(argv[1]) < 1 || int(argv[2]) < 1 || int(argv[3]) < 1){
fprintf(stderr, "Value error!\n");
return -2;
}
//初始化
sem_init(&(param->mutex), 0, 1);
sem_init(&(param->empty), 0, BUFFER_SIZE);
sem_init(&(param->full), 0, 0);
count = int(argv[1]);
pnum = int(argv[2]);
cnum = int(argv[3]);
param->pBUFFER = init_buffer(count);
ptid = (pthread *)malloc(pnum * sizeof(pthread));
citd = (pthread *)malloc(cnum * sizeof(pthread));
pthread_attr_init(&attr);
//创建生产者线程
for(i = 0;i < pnum;i++){
pthread_create(&ptid[i], &attr, producer, NULL);
}
//创建消费者线程
for(i = 0;i < cnum;i++){
pthread_create(&ctid[i], &attr, consumer, NULL);
}
//等待生产者线程结束
for(i = 0;i < pnum;i++){
pthread_join(ptid[i], NULL);
}
//等待消费者线程结束
for(i = 0;i < cnum;i++){
pthread_join(ctid[i], NULL);
}
printf("All done!");
sleep(2);
return 0;
}