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声明为全局变量所以系统自动初始化了!这方面的只是好久不看都忘了!*/
  • 相关阅读:
    @RequestParam注解使用:Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.
    cglib动态代理导致注解丢失问题及如何修改注解允许被继承
    springboot Autowired BeanNotOfRequiredTypeException
    git根据用户过滤提交记录
    不同包下,相同数据结构的两个类进行转换
    How to use Jackson to deserialise an array of objects
    jooq实践
    java如何寻找main函数对应的类
    Python--matplotlib
    Python 和 Scikit-Learn
  • 原文地址:https://www.cnblogs.com/leijiangtao/p/4759092.html
Copyright © 2011-2022 走看看