zoukankan      html  css  js  c++  java
  • pthread_cond_wait和pthread_cond_signal以及互斥变量的使用情况

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    #define BUFFER_SIZE 21 //初始化存储空间的大小
    #define END_FLAG (-1)//用于退出循环
    struct Products
    {
    int buffer[BUFFER_SIZE];//存储空间
    pthread_mutex_t locker; //声明互斥变量       
    pthread_cond_t notEmpty;//声明条件变量 
    pthread_cond_t notFull;
    int posReadFrom;
    int posWriteTo;
    };
    int flag1=0,flag2=0,num1=0,num2=0;//变量一定要记得初始化,很重要,前两个为了标记,后两个为了计数
    struct Products products; //定义结构体变量,下面要用到的
    int BufferIsFull(struct Products* products)//如果满,则返回1,否则返回0;
    {
    if ((products->posWriteTo + 1)%BUFFER_SIZE==products->posReadFrom)
    {
    return (1);
    }
    return (0);
    }
    
    int BufferIsEmpty(struct Products* products)//如果空,则返回1,否则返回0;
    {
    if ((products->posWriteTo)==(products->posReadFrom))
    {
    return (1);
    }
    
    return (0);
    }
    
    /*制造产品*/
    void Produce(struct Products* products, int item)
    {
    /*原子操作*/
    pthread_mutex_lock(&products->locker);
    /*无空间可写入*/
    while (BufferIsFull(products))
    {flag1=1;//标记变量
     pthread_cond_wait(&products->notFull, &products->locker);
    } 
    /*写入数据*/
    products->buffer[products->posWriteTo] = item;
    products->posWriteTo++;
    pthread_mutex_unlock(&products->locker);//在解锁之后发射信号
    /*发信*/
     if(flag2==2)
      {flag2=0;//这行代码至关重要,一开始我就是忘了写,然后会不断输出这句
      pthread_cond_signal(&products->notEmpty);
      printf("Produce调用了唤醒函数%d次
    ",++num1);//检查代码的执行情况是否正确,因为加入这行代码,更容易分析
      }
    
    }
    
    int Consume(struct Products* products)
    {
    int item;
    
    pthread_mutex_lock(&products->locker);
    /*为空时持续等待,无数据可读*/
    while (BufferIsEmpty(products))
    {flag2=2;
    pthread_cond_wait(&products->notEmpty, &products->locker);
    }
    /*提取数据*/
    item = products->buffer[products->posReadFrom];
    products->posReadFrom++;
    pthread_mutex_unlock(&products->locker);
    if(flag1==1)
    {flag1=0;pthread_cond_signal(&products->notFull); 
    printf("Consume调用了唤醒函数%d次
    ",++num2);}
    
    return item;
    }
    void* ProducerThread(void* data)
    {
    int i;
    for (i = 1; i <21; ++i)
    {
    printf("producer: %d
    ", i);
    Produce(&products, i);
    }
    Produce(&products, END_FLAG);
    return NULL;
    }
    
    void* ConsumerThread(void* data)
    {
    int item;
    
    while (1)
    {
    item = Consume(&products); 
    if (END_FLAG == item)
           break;
    printf("consumer: %d
    ", item);
    }
    return (NULL);
    }
    int main(int argc, char* argv[])
    {
    pthread_t producer;
    pthread_t consumer;
    int result;
    pthread_create(&producer, NULL, &ProducerThread, NULL);
    pthread_create(&consumer, NULL, &ConsumerThread, NULL);
    pthread_join(producer, (void *)&result);
    pthread_join(consumer, (void *)&result);
    printf("products.posReadFrom=%d
    ",products.posReadFrom);//测试循环次数
    printf("products.posWriteTo=%d",products.posWriteTo);
    exit(EXIT_SUCCESS);
    }
    //pthread_cond_signal此处我用了if进行判断,因为如果不进行判断,
    //则每次都会执行这句,信号发出去了,但是没人接收!(这个思想很重要的)
    /*为什么这个结构体变量没有初始化,反而它的两个数据成员,一开始都为0,
    真的让我不知道为啥,最后我终于明白了原来因为这个程序中把struct Products结构体变量,
    products声明为全局变量所以系统自动初始化了!这方面的只是好久不看都忘了!*/
  • 相关阅读:
    SpringBoot入门篇--读取资源文件配置
    SpringBoot入门篇--使用Thymeleaf模板引擎进行页面的渲染
    SpringBoot入门篇--热部署
    NOI2017 游记
    BZOJ 2754 【SCOI2012】 喵星球上的点名
    codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
    BZOJ 4407 于神之怒加强版
    BZOJ 2956 模积和
    BZOJ 4584 【APIO2016】 赛艇
    BZOJ 4591 【SHOI2015】 超能粒子炮·改
  • 原文地址:https://www.cnblogs.com/leijiangtao/p/4759092.html
Copyright © 2011-2022 走看看