• 多线程实现奇偶统计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;
    }
  • 相关阅读:
    C#ActiveX控件开发学习
    SPFA最短路算法
    用宏实现C/C++从非零整数开始的数组
    mysql学习笔记
    python学习笔记(多进程并发)
    python学习笔记(socket模块)
    jQuery学习笔记
    python学习笔记(IO模型)
    Django学习笔记
    导入Excel时启动Excel.exe进程出错
  • 原文地址:https://www.cnblogs.com/fallenmoon/p/6744596.html
Copyright © 2020-2023  润新知