条件变量通信机制

条件变量必须配合互斥锁一起实现对资源的互斥访问

使用方法:

int pthread_cond_init (pthread_cond_t *__restrict __cond, __const pthread_condattr_t *__restrict __cond_attr) :初始化条件变量,第二个参数是属性对象,NULL为默认

int pthread_cond_destroy (pthread_cond_t *__cond)销毁条件变量

int pthread_cond_signal (pthread_cond_t *__cond)通知等待条件变量的第一个线程,如果没有等待线程,则不起作用

int pthread_cond_broadcast (pthread_cond_t *__cond)通知等待的条件变量的所有线程,如果没有等待线程,则不起作用

int pthread_cond_wait (pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex)等待条件变量,第二个参数指向于条件变量关联的互斥锁指针

int pthread_cond_timewait (pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex, __const struct timespec *__restrict __abstime) :在指定时间内等待条件变量

在线程因等待条件变量进入等待状态时,将释放其申请的互斥锁。在等到条件变量时,会隐含申请到该互斥锁

条件变量实现读写锁

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include "pthread.h"
#define BUFFER_SIZE 2
//条件信息结构体
struct prodcons
{
int buffer[BUFFER_SIZE]; //生产产品值
pthread_mutex_t lock; //互斥锁
int readpos, writepos; //读写位置
pthread_cond_t notempty; //条件变量,表非空
pthread_cond_t notfull; //条件变量,表非满
}; //初始化
void init(struct prodcons *prod)
{
pthread_mutex_init(&prod->lock, NULL);
pthread_cond_init(&prod->notempty, NULL);
pthread_cond_init(&prod->notfull, NULL);
prod->readpos = ;
prod->writepos = ;
} //在缓冲区输入一个数据
void put(struct prodcons * prod, int data)
{
//锁定互斥锁
pthread_mutex_lock(&prod->lock);
while((prod->writepos + ) % BUFFER_SIZE == prod->readpos) //测试是否空间已满 注意 这里writepos的位置要加1 即保证下一个写入的位置是空的 ??
{
printf("producer wait for not full\n");
pthread_cond_wait(&prod->notfull, &prod->lock); //等待有空间写
}
//写数据
prod->buffer[prod->writepos] = data;
prod->writepos++;
if(prod->writepos >= BUFFER_SIZE)
prod->writepos = ;
pthread_cond_signal(&prod->notempty);
pthread_mutex_unlock(&prod->lock);
} //从缓冲区读一个数据
int get(struct prodcons * prod)
{
int data;
//锁定互斥锁
pthread_mutex_lock(&prod->lock);
while(prod->writepos == prod->readpos)
{
printf("producer wait for not empty\n");
pthread_cond_wait(&prod->notempty, &prod->lock);
}
data = prod->buffer[prod->readpos];
prod->readpos++;
if(prod->readpos >= BUFFER_SIZE)
prod->readpos = ;
pthread_cond_signal(&prod->notfull);
pthread_mutex_unlock(&prod->lock);
return data;
} #define OVER (-1)
struct prodcons buffer; //生产者
void * producer(void * data)
{
int n;
for(n = ; n <= ; n++) //生产5个产品
{
printf("producer sleep 1 second...\n");
sleep();
printf("put the %d product\n", n);
put(&buffer, n);
}
for(n = ; n <= ; n++)
{
printf("producer sleep 3 second...\n");
sleep();
printf("put the %d product\n", n);
put(&buffer, n);
}
put(&buffer, OVER);
printf("producer stopped!\n");
return NULL;
} //消费者
void * consumer(void * data)
{
int d = ;
while()
{
printf("consumer sleep 2 second...\n");
sleep();
d = get(&buffer);
printf("get the %d product\n", d);
if(d == OVER)
break;
}
printf("consumer stopped!\n");
return NULL;
} int main(int argc, char *argv[])
{
pthread_t th_a, th_b;
void * retval;
init(&buffer);
pthread_create(&th_a, NULL, producer, );
pthread_create(&th_b, NULL, consumer, );
pthread_join(th_a, &retval);
pthread_join(th_b, &retval);
return ;
}

验证,可用

【linux高级程序设计】(第十二章)Linux多线程编程 3的更多相关文章

  1. linux高级管理第十二章--rsync

    实验部分 1.安装rsync 2.配置文件 3.配置密码 4.后续 5.为了测试,创建几个文件 配置实时同步 1.调整inotify内核参数 安装inotify-tools 测试同步 编写脚本 验证 ...

  2. 读书笔记 - js高级程序设计 - 第十二章 DOM2和DOM3

      Node类型的变化   访问元素的样式 myDiv.style.backgroundColor = "red" myDiv.style.width = "100px& ...

  3. 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条

    http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程 ...

  4. 鸟哥的linux私房菜——第十二章学习(Shell Scripts)

    第十二章  Shell Scripts 1.0).什么是shell scripts? script 是"脚本.剧本"的意思.整句话是说, shell script 是针对 shel ...

  5. 读书笔记 - js高级程序设计 - 第十五章 使用Canvas绘图

    读书笔记 - js高级程序设计 - 第十三章 事件   canvas 具备绘图能力的2D上下文 及文本API 很多浏览器对WebGL的3D上下文支持还不够好   有时候即使浏览器支持,操作系统如果缺缺 ...

  6. 鸟哥的Linux私房菜——第十二章:档案的压缩与打包

    视频链接: 土豆:http://www.tudou.com/programs/view/GncwT0FJKsQ B站(推荐):http://www.bilibili.com/video/av98857 ...

  7. 第三十二章 Linux常规练习题(一)

    一.练习题一 1.超级用户(管理员用户)提示符是____,普通用户提示符是____.2.linux关机重启的命令有哪些 ?3.bash是什么?4.bash特性, 常见的bash特性有哪些?5.网卡的配 ...

  8. 第十二章 Linux三剑客之老三—grep

    一.Linux grep 命令用于查找文件里符合条件的字符串. Linux系统中的grep命令是一种功能强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.grep全称是Global ...

  9. 【linux高级程序设计】(第九章)进程间通信-管道 1

    Linux操作系统所支持的主要进程间的通信机制. 无名管道 PIPE cat test.txt| grep hello 上面这种管道,将一个命令的输出作为另一个命令的输入,而这种管道是临时的,命令执行 ...

  10. 第十二章Linux文件系统与日志

    1.inode 包含文件的元信息(1)inode 内容:文件的字节数.拥有者的 UID.GID.文件的读写执行权限.时间戳等,但不包含文件名.文件名是储存在目录的目录项中.(2)查看文件的 inode ...

随机推荐

  1. TouTiao开源项目 分析笔记14 段子评论

    1.段子页面详情 1.1.先看看预览界面吧 左边的页面已经实现了,现在的目的就是要实现点击左侧的每一个item 然后跳转到右边相应的段子详情页面. 1.2.首先肯定有右侧这个活动==>JokeC ...

  2. TouTiao开源项目 分析笔记11 以总体到局部的思路 构建图片主列表

    1.构建图片主列表的整体片段PhotoTabLayout 1.1.首先创建一个PhotoTabLayout片段 public class PhotoTabLayout extends Fragment ...

  3. Android 第三方库RxLifecycle使用

    1.简单介绍RxLifecycle 1.1.使用原因. 在使用rxjava的时候,如果没有及时解除订阅,在退出activity的时候,异步线程还在执行. 对activity还存在引用,此时就会产生内存 ...

  4. Wind Of Change

    Wind of change until the end  变革的风一直吹直至最后 You will see that I will be your friend 你会看见我成为你的朋友 If you ...

  5. 踩到Framework7 Photo Browser 的一个坑

    最近在做的项目用了Framework7前端框架,功能确实比较强大!但这两天遇到一个坑,希望我的这点收获能给遇到这个问题的朋友一点帮助. 在使用Photo Browser 的时候,图片下方想放一个“点赞 ...

  6. 孤荷凌寒自学python第六十六天学习mongoDB的基本操作并进行简单封装5

    孤荷凌寒自学python第六十六天学习mongoDB的基本操作并进行简单封装5并学习权限设置 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十二天. 今天继续学习mongo ...

  7. c++知识点总结--友元&运算符重载

    友元函数(不属于类) 可以访问类的私有变量,以及私有函数 友元函数在类内声明需要friend关键字,类外定义就不需要 友元函数可以直接在类内定义 友元函数必须包含对象指针   友元类(不适用继承,只适 ...

  8. Alpha 冲刺

    队名:我头发呢队 组长博客 作业博客 杰(组长) 过去两天完成了哪些任务 查阅Python爬取音源的资料,如 Python3爬虫抓取网易云音乐热评实战 Python爬取高品质QQ音乐(2) 如何爬网易 ...

  9. selenium webdriver——JavaScript警告窗处理

    在WebDriver中处理JavaScript所生成的alert.confirm以及prompt,具体方法是使用switch_to_alert()方法定位到alert.confirm以及 prompt ...

  10. kvm竟然抓不到kvm的tracepoint

    今天终于把kvm给搭起来了,打开了host机的tracepoint竟然一个都没有抓到,这是咋回事? 难道kvm的东西只有在启动的时候才会被抓到? 虚拟出来一块内存一块CPU,虚拟出来一个内存.感觉都好 ...