所谓进步就是与知识的缘分与不期而遇,本来选嵌入式课程是为了学习嵌入式应用方面的知识,没想到竟然把生产者消费者问题学懂了。其实程序中最核心的部分是读者与写着在临界区部分的代码,用三个信号量锁住线程使得同一时刻只能有一个线程进入临界区。
本程序中写者与写者互斥,读者与读者互斥,写者与读者也互斥。
其实这个程序还可以提高效率,让读者与写着不互斥,实现时只需在读者与写者线程中使用独立的二值信号量即可。
本程序在fedora14(Linux环境)下实现.
//coded by abilitytao
//2012.6.2
//department of computer science ,Nanjing university.
//advisor:professor Jianxin Yu
//aided by Junjie Ye and XiaoLin Ma
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<pthread.h>
#include<errno.h>
#include<semaphore.h>
#include<sys/ipc.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#define BUFFER_SIZE 8 //attention: it shoud be at least ONE!
#define REAL_BUFFER (BUFFER_SIZE+2)
#define RUN_TIME 2 //run time : programme terminate after <RUN_TIME> seconds
#define WRITER_NUM 4 //define the number of writer
#define READER_NUM 3 //define the number of reader
/**///////////////////////////////////////////////QUEUE/////////////////////////////////////////////////////struct node
{
char data[64];
}queue[REAL_BUFFER];
int front;
int rear;
int nQueue;//the number the queue contains
struct node rand_one_node()
{
struct node ans;
int i;
for(i= 0 ;i< 9 ;i++)
{
int tem = rand()%10;
ans.data[i]='0'+tem;
}
ans.data[9]=' ';
for(i = 10; i < 64 ; i++)
{
int tem = rand()%26;
ans.data[i]='a'+tem;
}
return ans;
}
void print_node(struct node x)
{
int i;
for(i = 0;i< 64 ;i++)
printf("%c",x.data[i]);
}
void queue_init()
{
front = 1;
rear = 0;
nQueue = 0;
}
int is_queue_full(void)
{
if( (front + 1) % REAL_BUFFER == rear )
return 1;
else
return 0;
}
int is_queue_empty(void)
{
if( (rear + 1)% REAL_BUFFER == front )
return 1;
else
return 0;
}
void queue_pushback(struct node x)//
{
if(is_queue_full())
{
printf("the queue is full,please check it befor");
return ;
}
queue[front]=x;
front+=1;
front%=BUFFER_SIZE + 2;
nQueue++;
}
struct node queue_popfirst()
{
if(is_queue_empty())
{
printf("the queue is empty,please check it befor");
}
else
{
rear+=1;
rear%=REAL_BUFFER;
return queue[rear];
nQueue--;
}
}
/**///////////////////////////////////////END FOR QUEUE///////////////////////////////////////////
int fd;
FILE *file;
time_t end_time;
sem_t mutex,full,avail;
void *producer(void *arg)
{
int real_write;
int delay_time = 0;
while(time(NULL) < end_time)
{
sem_wait(&avail);
sem_wait(&mutex);
struct node tem = rand_one_node();//generate a node
//judge if the queue if full
if(!is_queue_full())
queue_pushback(tem);
//write a node into queue
printf("\nWrite:\n");
print_node(tem);
printf("\nto the FIFO\n");
printf("producer delay = %d\n",delay_time);
//judge if the queue if full
if(is_queue_full())
printf("\n******************\nthe queue is full\n******************\n\n");
//sleep for some time
delay_time = (int) (rand()%190) + 10;//delay time between 10 ~ 200 ms
usleep(delay_time);
sem_post(&full);
sem_post(&mutex);
}
pthread_exit(NULL);
}
void *customer(void *arg)
{
int i;//a counter
int delay_time;
while(time(NULL) < end_time)
{
sem_wait(&full);
sem_wait(&mutex);
struct node tem;
//judge if the queue is empty
if(!is_queue_empty())
tem = queue_popfirst();
//output the node info in the file
for(i = 0;i < 64 ;i++)
fprintf(file,"%c",tem.data[i]);
fprintf(file,"\n");
//read a node
printf("\nRead:\n");
print_node(tem);
printf("\nfrom the FIFO\n");
printf("reader delay = %d\n",delay_time);
//judge if the queue if full
if(is_queue_empty())
printf("\n******************\nthe queue is empty\n******************\n\n");
//sleep for some time
delay_time = (int) (rand()%80) + 20; // delay time between 20 ~ 100 ms
usleep(delay_time);
sem_post(&avail);
sem_post(&mutex);
}
pthread_exit(NULL);
}
int main()
{
//init file point
freopen("out.txt","w",stdout);
file = fopen("G2_ReaderWriter.txt","w");
//init the queue
queue_init();
//generate run time
srand(time(NULL));
end_time = time(NULL) +RUN_TIME;
pthread_t threadWriter[WRITER_NUM];
pthread_t threadReader[READER_NUM];
//pthread_t thrd_prd_id,thrd_cst_id;
//pthread_t mon_th_id;
sem_init(&mutex,0,1);
sem_init(&avail,0, BUFFER_SIZE);
sem_init(&full,0,0);
int i;//counter
//create writer thread
for(i = 0 ;i < WRITER_NUM ; i++ )
pthread_create(&threadWriter[i], NULL, producer, NULL);
//create reader thread
for(i = 0 ;i < READER_NUM ; i++ )
pthread_create(&threadReader[i], NULL, customer, NULL);
//wait for quit of writer
for(i =0 ;i<WRITER_NUM ;i++)
pthread_join(threadWriter[i],NULL);
//wait for quit of reader
for(i = 0;i<READER_NUM ;i++)
pthread_join(threadReader[i],NULL);
fclose(file);//close file point
fclose(stdout);
return 0;
}
PS:此为2012年嵌入式课程大作业,若助教查询到此网页,请核对我的信息以免误认为是作弊.谢谢!