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=,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以及互斥变量的使用情况的更多相关文章
- 关于 pthread_cond_wait 和 pthread_cond_signal , signal 无效的问题
关于一个消费者模式,,,引起的问题.. 我在io线程里不断的把一个函数调用放到队列里 然后ruby线程就不断的从这个队列里取出函数之争并运行. 典型的 消费者模式. 我曾经以为是这样... 这是wor ...
- 条件变量pthread_cond_wait()和pthread_cond_signal()详解
条件变量 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起:另一个线程使"条件成立" ...
- 深入理解pthread_cond_wait、pthread_cond_signal
===============================man pthread_cond_wait的解释========================== LINUX环境下多线程编程肯定会遇到 ...
- 面试题:如何在不使用临时变量temp的情况下交换两个整数的值?
利用一个小技巧,一个整数a在异或另一个整数b两次以后所得的值还是整数a. 具体的过程我们可以自己找两个整数以二进制的形式自己在纸上画一下他们的异或过程.(异或的运算符号为"^") ...
- 继承时,当父子类都具有相同的成员变量,默认情况下是直接调用子类的成员变量,当要调用父类的成员变量则需要使用super关键之
package day02; public class Person { String name="fl"; }class Car{ }class Student extends ...
- 【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) 需要检查的步骤: ...
- 线程相关函数(6)-pthread_cond_wait(),pthread_cond_signal(), 条件变量
pthread_cond_tpthread_cond_initpthread_cond_destroypthread_cond_waitpthread_cond_timedwaitpthread_co ...
- linux多线程-互斥&条件变量与同步
多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include < ...
- node源码详解(七) —— 文件异步io、线程池【互斥锁、条件变量、管道、事件对象】
本作品采用知识共享署名 4.0 国际许可协议进行许可.转载保留声明头部与原文链接https://luzeshu.com/blog/nodesource7 本博客同步在https://cnodejs.o ...
随机推荐
- php中array_merge合并数组详解
如果键名有重复,该键的键值为最后一个键名对应的值(后面的覆盖前面的).如果数组是数字索引的,则键名会以连续方式重新索引. 注释:如果仅仅向 array_merge() 函数输入了一个数组,且键名是整数 ...
- 5.翻译:EF基础系列---EF中的上下文类
原文地址:http://www.entityframeworktutorial.net/basics/context-class-in-entity-framework.aspx EF中的上下文类是一 ...
- postman 脚本学习
pm的脚本断言库默认似乎是集成chaijs的.所以重点也要掌握chaijs的用法,其实和其他断言库类似.玩着玩着就会了.推荐看看 简书 chaijs 中文文档 传送门: # pm 脚本的教程 http ...
- 验证码识别 图像降噪 算法 Python (二)
处理器图像: 处理后图像: 代码: from PIL import Image image = Image.open('4.jpg') image = image.convert('L') image ...
- Macos mysql 8.0.11 添加配置文件
mac 安装mysql 后,没有配置文件,如果需要添加配置文件,需要在/etc 目录下面添加 my.cnf 文件. 添加方法 打开文件命令:sudo vi /etc/my.cnf 文件添加内容: [ ...
- Django form入门详解--2
调整form的输出格式: 默认情况下form的格式化输出是基本table的样式的.但是django中还是为form提供发别的输出样式 1.默认的table样式输出 <html> <h ...
- 定期删除elasticsearch 的index 索引
#!/bin/bashfind /data/elasticsearch/data/pro-kz-log/nodes/0/indices/ -type d -mtime +7 | awk -F" ...
- Kubernetes的系统架构与设计理念
Kubernetes与云原生应用简介 随着Docker技术的发展和广泛流行,云原生应用和容器调度管理系统也成为IT领域大热的词汇.事实上,云原生应用的思想,在Docker技术火爆之前,已经由云计算技术 ...
- cocopods 问题
http://www.cocoachina.com/bbs/read.php?tid=1711580
- IOS 设备备份文件详解 (一)
IOS设备如果没有越狱的话想获取一些敏感的信息还是有写复杂的,比如获取上网信息,短信,通话记录等等这些,但是有一个通用的方法可以获取到这些信息,那就是IOS 设备的备份功能.文章不涉及如何备份以及恢复 ...