#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=,flag2=,num1=,num2=;//变量一定要记得初始化,很重要,前两个为了标记,后两个为了计数
struct Products products; //定义结构体变量,下面要用到的
int BufferIsFull(struct Products* products)//如果满,则返回1,否则返回0;
{
if ((products->posWriteTo + )%BUFFER_SIZE==products->posReadFrom)
{
return ();
}
return ();
} int BufferIsEmpty(struct Products* products)//如果空,则返回1,否则返回0;
{
if ((products->posWriteTo)==(products->posReadFrom))
{
return ();
} return ();
} /*制造产品*/
void Produce(struct Products* products, int item)
{
/*原子操作*/
pthread_mutex_lock(&products->locker);
/*无空间可写入*/
while (BufferIsFull(products))
{flag1=;//标记变量
pthread_cond_wait(&products->notFull, &products->locker);
}
/*写入数据*/
products->buffer[products->posWriteTo] = item;
products->posWriteTo++;
pthread_mutex_unlock(&products->locker);//在解锁之后发射信号
/*发信*/
if(flag2==)
{flag2=;//这行代码至关重要,一开始我就是忘了写,然后会不断输出这句
pthread_cond_signal(&products->notEmpty);
printf("Produce调用了唤醒函数%d次\n",++num1);//检查代码的执行情况是否正确,因为加入这行代码,更容易分析
} } int Consume(struct Products* products)
{
int item; pthread_mutex_lock(&products->locker);
/*为空时持续等待,无数据可读*/
while (BufferIsEmpty(products))
{flag2=;
pthread_cond_wait(&products->notEmpty, &products->locker);
}
/*提取数据*/
item = products->buffer[products->posReadFrom];
products->posReadFrom++;
pthread_mutex_unlock(&products->locker);
if(flag1==)
{flag1=;pthread_cond_signal(&products->notFull);
printf("Consume调用了唤醒函数%d次\n",++num2);} return item;
}
void* ProducerThread(void* data)
{
int i;
for (i = ; i <; ++i)
{
printf("producer: %d\n", i);
Produce(&products, i);
}
Produce(&products, END_FLAG);
return NULL;
} void* ConsumerThread(void* data)
{
int item; while ()
{
item = Consume(&products);
if (END_FLAG == item)
break;
printf("consumer: %d\n", 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\n",products.posReadFrom);//测试循环次数
printf("products.posWriteTo=%d",products.posWriteTo);
exit(EXIT_SUCCESS);
}
//pthread_cond_signal此处我用了if进行判断,因为如果不进行判断,
//则每次都会执行这句,信号发出去了,但是没人接收!(这个思想很重要的)
/*为什么这个结构体变量没有初始化,反而它的两个数据成员,一开始都为0,
真的让我不知道为啥,最后我终于明白了原来因为这个程序中把struct Products结构体变量,
products声明为全局变量所以系统自动初始化了!这方面的只是好久不看都忘了!*/

pthread_cond_wait和pthread_cond_signal以及互斥变量的使用情况的更多相关文章

  1. 关于 pthread_cond_wait 和 pthread_cond_signal , signal 无效的问题

    关于一个消费者模式,,,引起的问题.. 我在io线程里不断的把一个函数调用放到队列里 然后ruby线程就不断的从这个队列里取出函数之争并运行. 典型的 消费者模式. 我曾经以为是这样... 这是wor ...

  2. 条件变量pthread_cond_wait()和pthread_cond_signal()详解

    条件变量        条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起:另一个线程使"条件成立" ...

  3. 深入理解pthread_cond_wait、pthread_cond_signal

    ===============================man pthread_cond_wait的解释========================== LINUX环境下多线程编程肯定会遇到 ...

  4. 面试题:如何在不使用临时变量temp的情况下交换两个整数的值?

    利用一个小技巧,一个整数a在异或另一个整数b两次以后所得的值还是整数a. 具体的过程我们可以自己找两个整数以二进制的形式自己在纸上画一下他们的异或过程.(异或的运算符号为"^") ...

  5. 继承时,当父子类都具有相同的成员变量,默认情况下是直接调用子类的成员变量,当要调用父类的成员变量则需要使用super关键之

    package day02; public class Person { String name="fl"; }class Car{ }class Student extends ...

  6. 【mybatis】mybatis访问报错:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) 或者 feign被调用方使用的mybatis总报空指针异常java.lang.NullPointerException,而变量都没有问题的情况

    mybatis访问报错:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) 需要检查的步骤: ...

  7. 线程相关函数(6)-pthread_cond_wait(),pthread_cond_signal(), 条件变量

    pthread_cond_tpthread_cond_initpthread_cond_destroypthread_cond_waitpthread_cond_timedwaitpthread_co ...

  8. linux多线程-互斥&条件变量与同步

    多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include < ...

  9. node源码详解(七) —— 文件异步io、线程池【互斥锁、条件变量、管道、事件对象】

    本作品采用知识共享署名 4.0 国际许可协议进行许可.转载保留声明头部与原文链接https://luzeshu.com/blog/nodesource7 本博客同步在https://cnodejs.o ...

随机推荐

  1. SteveY对Amazon和Google平台的吐槽

    Steve Yegge, Amazon的前员工,现任Google员工,其本来想在Google+上和Google的员工讨论一些关于平台的东西,结果不小心把圈子设成了Public,结果这篇文章就公开给了全 ...

  2. C语言的整型溢出问题

    整型溢出有点老生常谈了,bla, bla, bla… 但似乎没有引起多少人的重视.整型溢出会有可能导致缓冲区溢出,缓冲区溢出会导致各种黑客攻击,比如最近OpenSSL的heartbleed事件,就是一 ...

  3. 【转载并整理】mysql排序

    由于oracle中有排序函数,可以使用over的语句方便排序,但是mysql中没有 这里碰到几个mysql的概念:用户变量.系统变量.if语句.函数GROUP_CONCAT 1. 可以使用定义变量(@ ...

  4. android surfaceView 的简单使用 画图,拖动效果

    前面说到了画图,其实更好的就是使用 surfaceView了. surfaceView 继承于 View,View里面嵌套了一个专门用于画图的 surface, 对于一个View的onDraw()方法 ...

  5. 一个将java事物的非常好的栗子

    地址:http://www.cnblogs.com/davenkin/archive/2013/02/16/java-tranaction-1.html

  6. Java – How to convert String to Char Array

    Java – How to convert String to Char ArrayIn Java, you can use String.toCharArray() to convert a Str ...

  7. 另辟蹊径 直取通州的“墨迹天气”APP应用的成功故事

    一个天气应用,曾被认为是要挑战国家气象局,网站也莫名其妙地被封,两个合伙人先后离开.创始人金犁是如何把这么一款工具类应用做到人所共知的? 采访 | 郑江波 翟文婷 文 | 翟文婷 出生时间:1982年 ...

  8. yarn 的安装

    yarn的安装方法: https://yarn.bootcss.com/docs/install.html#linux-tab

  9. php分享三十:php版本选择

    思考: cgi是怎么运行的?(是多线程?多进程?单线程?单进程?) fastcgi运行原理? apache运行php的原理? (是多进程还是多线程?) nginx是怎么运行php的? 什么是安全模式和 ...

  10. Word 2010之简单图文混排

    所谓图文混排,就是指将图片与文本内容进行一定规律的排列,以让文档更加漂亮. 下面的示范是一个简单的将两副照片混排到文字当中的(图片与文本内容无关,仅供演示). 1. 打开Word,输入文本内容: 2. ...