主要是为了解决有限缓存问题。使用三个信号量:empty(记录有多少空位),full(记录有多少满位)以及mutex(二进制信号量,保护对缓存的插入和删除操作)。
开发环境:Ubuntu 12.10+codeBlocks
class buffer:
Buffer.h
/*********************
author zhu
date 2014-4-12
*********************/
typedef int buffer_item; //define buffer_item to be int
#define BUFFER_SIZE 5 //define the size of the array is 5
#include<pthread.h>
#include<semaphore.h>
//the interface of the buffer
class Buffer
{
public:
Buffer(); //constructor
bool isEmpty(); //judge whether the array is empty
bool isFull(); //judge whether the array is full
int insert_item(buffer_item item); //insert item into the array
int remove_item(buffer_item *item); //remove item from the head
//int getSize(); //return the size of the array
sem_t *get_empty(); //return the address of empty
sem_t *get_full(); //return the addess of full
pthread_mutex_t *get_mutex(); //return the adress of mutex
private:
//int size;
int front,rear; //head and end
sem_t empty,full; //semaphore that stand for the state of empty or full
pthread_mutex_t mutex; //binary semaphore
};
Buffer.cpp
#include <iostream>
#include "Buffer.h"
using namespace std;
buffer_item buffer[BUFFER_SIZE];//cicle array
Buffer::Buffer()//initialize
{
//size = 0;
front = 0;
rear = 0;
pthread_mutex_init(&mutex,NULL);
sem_init(&full,0,0);
sem_init(&empty,0,5);
}
bool Buffer::isEmpty()
{
//if the front is equal to rear,the array is empty
if(rear==front)
return true;
return false;
}
bool Buffer::isFull()
{
//judge whether the array is full
if(front==(rear+1)%BUFFER_SIZE)
return true;
return false;
}
int Buffer::insert_item(buffer_item item)
{
if(!isFull())
{
//insert into the array
buffer[rear] = item;
//++size;
//rear forword one step
rear = (rear+1)%BUFFER_SIZE;
return 0;
}
return 1;
}
int Buffer::remove_item(buffer_item *item)
{
if(!isEmpty())
{
//--size;
//get the value of the item to be delete
*item = buffer[front];
//front forword one step
front = (front+1)%BUFFER_SIZE;
return 0;
}
return 1;
}
//int Buffer::getSize()
//{
// return size;
//}
sem_t* Buffer::get_empty()
{
return ∅
}
sem_t* Buffer::get_full()
{
return &full;
}
pthread_mutex_t* Buffer::get_mutex()
{
return &mutex;
}
Test function:
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<cstdio>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>
#include "Buffer.h"
using namespace std;
void *producer(void*);//the handler function of producer
void *consumer(void*);//the handler function of consumer
//the entrance of the program
int main(int argc,char *argv[])
{
int slptime = 1000;//atoi(argv[0]);//sleep time
int pro_num = 2;//atoi(argv[1]);//the number of producer thread
int con_num = 3;//atoi(argv[2]);//the number of consumer thread
Buffer testBf;//initialize the data member
//declare the array of producer and consumer
pthread_t *tid1 = new pthread_t[pro_num];
pthread_t *tid2 = new pthread_t[con_num];
//create the thread of producer and consumer
for(int i=0;i<pro_num;++i)
{
pthread_create(&tid1[i],NULL,producer,&testBf);
}
for(int j=0;j<con_num;++j)
{
pthread_create(&tid2[j],NULL,consumer,&testBf);
}
sleep(20);//the sleep time
delete[]tid1;//release the space
delete[]tid2;
return 0;
}
void *producer(void *param)
{
Buffer *buff = (Buffer*)param;//achieve the buffer
buffer_item brand;
srand(time(0));
while(true)
{
sem_wait(buff->get_empty());//wait
pthread_mutex_lock(buff->get_mutex());//lock
sleep(rand()%3);//sleep randomly from 0 to 3 seconds
brand = rand();//produce a rand number range from 0 to RAND_MAX
cout << "Producer produced "<< brand << endl;
//insert into the array
if(buff->insert_item(brand))
cout << "Report error condition." << endl;
pthread_mutex_unlock(buff->get_mutex());//unlock
sem_post(buff->get_full());//single
}
}
void *consumer(void *param)
{
Buffer *buff = (Buffer*)param;//achieve the buffer
buffer_item brand;
srand(time(0));
while(true)
{
sem_wait(buff->get_full());//wait
pthread_mutex_lock(buff->get_mutex());//lock
sleep(rand()%3);
if(buff->remove_item(&brand))//remove rear and get the item
cout << "Report error condtion." << endl;
else
cout << "Consumer consumed " << brand << endl;
pthread_mutex_unlock(buff->get_mutex());//unlock
sem_post(buff->get_empty());//singnal
}
}
运行结果:
这是一次操作系统的作业,中间也经历了一些波折,由于这次文件相对较多,采用vim+g++操作起来稍微比较麻烦,自己的水平也没有达到那种水平,于是装IDE,尝试了好几个也没找到合适的感觉,终于我发现了CodeBlock,在这就要推荐一下了,无论是界面还是操作性我都很喜欢,虽然后来遇到链接问题,不过也都解决了。值得一提的是在安装了这么多IDE后,中间的卸载过程还把系统搞坏了,无奈重装,当时看到提示说可以修复,安装的软件和文件都可以保存结果装好之后遇上分辨率和无线网络连不上的问题,查了之后众说纷纭还是没有解决,最后老老实实重装,嘿嘿,这次倒是没问题了。网络的资源是无限的,搜索是一项技能!