#include <stdio.h> #include <stdlib.h> #include <time.h> #include "pthread.h" #define WRITE_NUM 1000 #define OVER (110000) #define WRITE_SIZE 6 //写进程一次写的个数 int count=0; //统计已写的数据量 /* 设置一个整数的圆形缓冲区 */ struct prodcons { int buffer[WRITE_SIZE+1]; /* 缓冲区数组 */ pthread_mutex_t lock; /* 互斥锁 */ int readpos, writepos; /* 读写的位置*/ int ji, ou, zheng, fu, zero; //奇数、偶数、正数、负数,零的个数 int iswrite; //标志是否可写 //这下面的两个信号很重要啊 pthread_cond_t readable; /* 缓冲区非空信号 */ pthread_cond_t writeable; /*缓冲区非满信号 */ }; /*--------------------------------------------------------*/ /*初始化缓冲区*/ void init(struct prodcons * b) { pthread_mutex_init(&b->lock, NULL); pthread_cond_init(&b->readable, NULL); pthread_cond_init(&b->writeable, NULL); b->readpos = 0; b->writepos = 0; b->ji=0; b->ou=0; b->zheng=0; b->fu=0; b->zero=0; b->writepos=0; b->iswrite=1; b->iswrite=1; } /*--------------------------------------------------------*/ /* 向缓冲区中写入WRITE_SIZE个整数*/ void put(struct prodcons * b) { int i,data; pthread_mutex_lock(&b->lock); while(!b->iswrite){ // if(!b->iswrite){ printf("wait for read pthread "); pthread_cond_wait(&b->writeable, &b->lock); } /*写数据并且指针前移*/ //我写进程一次性要写WRITE_SIZE个数 srand(time(0)); for(;b->writepos!=WRITE_SIZE;b->writepos++){ data=rand()%1000-500; b->buffer[b->writepos] = data; printf(" wirte-->%d ", data); //0~WRITE_NUM-1 已经写够了 if(count++==WRITE_NUM-1){ //如果刚好这一次缓冲区全部写满,而且,数据也全部写完了 //那么,就会有问题 //所以,缓冲区要比WRITE_SIZE大1 b->buffer[++(b->writepos)]=OVER; b->writepos++; //为了和一般情况下的有效数据做形式上的统一,都是指向有效数据的下一个位置 break; } } /*设置缓冲区非空信号*/ b->readpos=0; //写完之后读进程当然该从0位置开始读 b->iswrite=0; pthread_cond_signal(&b->readable); pthread_mutex_unlock(&b->lock); } /*--------------------------------------------------------*/ /*从缓冲区中读出一个整数 */ int get(struct prodcons * b) { int data; pthread_mutex_lock(&b->lock); while(b->iswrite){ // if(b->iswrite){ printf("wait for write pthread "); pthread_cond_wait(&b->readable, &b->lock); } // b->iswrite=1; /* 读数据并且指针前移 */ data = b->buffer[b->readpos]; //如果不是结束符,统计 if(data!=OVER){ if(data%2==0) b->ou++; else b->ji++; if(data==0) b->zero++; else if(data>0) b->zheng++; else b->fu++; }else{ pthread_mutex_unlock(&b->lock); return data; } b->readpos++; if(b->readpos==b->writepos){ //缓冲区读完了,写进程当然得从0位置开始写 b->writepos=0; b->iswrite=1; /* 设置缓冲区非满信号*/ pthread_cond_signal(&b->writeable); } pthread_mutex_unlock(&b->lock); return data; } /*--------------------------------------------------------*/ struct prodcons buffer; /*--------------------------------------------------------*/ void * producer(void * data) { int n; for (;;) { put(&buffer); if(count==WRITE_NUM) break; } printf("producer stopped! "); pthread_exit(NULL); } /*--------------------------------------------------------*/ void * consumer(void * data) { int d; while (1) { d = get(&buffer); if (d == OVER ) break; printf(" %d-->read ", d); } printf("consumer stopped! "); pthread_exit(NULL); } /*--------------------------------------------------------*/ int main(void) { pthread_t th_a, th_b; void * retval; init(&buffer); pthread_create(&th_a, NULL, producer, 0); pthread_create(&th_b, NULL, consumer, 0); /* 等待生产者和消费者结束 */ pthread_join(th_a, &retval); pthread_join(th_b, &retval); printf("奇数个数:%d ",buffer.ji); printf("偶数个数:%d ",buffer.ou); printf("正数个数:%d ",buffer.zheng); printf("负数个数:%d ",buffer.fu); printf("零的个数:%d ",buffer.zero); return 0; }