多线程实现奇偶统计v2

#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;
}
原文地址:https://www.cnblogs.com/fallenmoon/p/6744596.html