主要是为了解决有限缓存问题。使用三个信号量: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 };
#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; }
#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后,中间的卸载过程还把系统搞坏了,无奈重装,当时看到提示说可以修复,安装的软件和文件都可以保存结果装好之后遇上分辨率和无线网络连不上的问题,查了之后众说纷纭还是没有解决,最后老老实实重装,嘿嘿,这次倒是没问题了。网络的资源是无限的,搜索是一项技能!