#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. PowerShell 获取Site Collection下被签出的文件

    由于权限的设置,当文件被签出时导致别人不可见了,这对校验文件个数的人来说着实是件烦恼的事.幸好利用PowerShell,可以获取Site Collection下被签出的文件. Resolution A ...

  2. 当 Swoole 遇上 ThinkPHP5 世界你好

    本文假设你已经有了 Linux 操作系统的 PHP 环境,强烈推荐使用 Vagrant 来搭建开发环境 安装 Swoole PECL 拓展 可以通过 pecl 命令或者通过源码包编译安装,本文采用 p ...

  3. Java – Display all ZoneId and its UTC offset

    package com.mkyong.date; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.Z ...

  4. SQL 教程数据库包括:Oracle, Sybase, SQL Server, DB2, Access 等等,您将学到如何使用 SQL 访问和处理数据系统中的数据

    SQL 基础教程 SQL 教程 SQL 简介 SQL 语法 SQL select SQL distinct SQL where SQL AND & OR SQL Order By SQL in ...

  5. php分享十五:php的数据库操作

    一:术语解释: What is an Extension? API和扩展不能理解为一个东西,因为扩展不一定暴露一个api给用户 The PDO MySQL driver extension, for ...

  6. Axure chrome 扩展显示已损坏的解决方法

    下载地址 链接:https://pan.baidu.com/s/11K3t_mvgJg51siO_jNRejg 提取码:goz1 如果链接失效,请留言或站内信提醒我更新 疑问 之前用的好好的Axure ...

  7. Oozie workflow工作流action间参数传递实现

    假设workflow里有两个action节点,shell和hive,hive需要用到shell节点里的值,shell脚本如下 #!/bin/sh day=`date '+%Y%m%d%H'` echo ...

  8. Java:多线程,CyclicBarrier同步器

    1. 背景 CyclicBarrier类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此 ...

  9. 牛腩学Kotlin做Android应用

    牛腩学Kotlin做Android应用,蹭热度视频,边学边做, 01-kotlin插件安装及hello world 02-kotlin基础语法速览 哔哩哔哩观看地址:http://www.bilibi ...

  10. IOS高访微信聊天对话界面(sizeWithFont:constrainedToSize和stretchableImageWithLeftCapWidth的使用)

    大家好,百忙之中,抽出点空,写个微博,话说好久没写. 最近项目中有碰到写类似微信聊天界面上的效果,特整理了一下,写了一个小的Demo,希望给没头绪的同学们一个参考! 下载地址:http://files ...