条件变量通信机制

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

使用方法:

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. P3365 改造二叉树

    P3365 改造二叉树 链接 分析: 求出中序遍历后,然后使其变成上升子序列.过程:每个点减去坐标,然后nlogn求出最长不下降子序列,n-ans即答案. 做题时一直认为二叉树就是完全二叉树,然后一直 ...

  2. css3 3D

    开通黄钻 Css3 -3D效果<!DOCTYPE html><html lang="en"><head> <meta charset=&q ...

  3. 手把手教你如何逐步安装OpenStack

    [TechTarget中国原创] 尽管OpenStack官方提供的在线安装教程和分步向导能够为管理员提供很大帮助,但是依然存在很多不尽如人意的地方.因此在Ubuntu上安装OpenStack的过程当中 ...

  4. 云计算之路-阿里云上:OCS问题的进展以及11:30-11:50遇到的问题

    (上图是今天出问题期间Web服务器性能监控图,紫色表示的是Request Execution Time) 昨天我们发布了一篇博客分享了我们这两天遇到的OCS(开放缓存服务)问题,详见云计算之路-阿里云 ...

  5. NOIP 2018 总结

    NOIP 2018 总结 提高组: 应得分 \(100 + 100 + 40 + 100 + 50 + 44 = 434\). 考后期望得分 \(100 + 100 + 20 + 100 + 50 + ...

  6. Google浏览器历史版本下载地址和驱动器对应关系地址分享

    Google浏览器历史版本下载地址https://www.slimjet.com/chrome/google-chrome-old-version.php google webdriver下载地址分享 ...

  7. Flask 教程精简版之一(系列片)

    Flask 教程精简版之一(系列片) 现在连教程都有精简版 准备 1.要学会 Flask 之前必须掌握 Python 基本使用. 2.会使用简单的 HTML 效果更加 3.若想练气功必须先自暴自弃 简 ...

  8. PHP vscode+XDebug 远程断点调试服务器上的代码

    对于简单的项目或仅仅想知道某一位置的某个变量是什么值,直接使用var_dump配置exit来打印和中断就可以了,方便又快捷, 而对于大型项目的调试,或想了解某个系统的整个运行过程,xdebug可能会是 ...

  9. Visual C++ 图像处理类库CxImage源代码

    说明:VC++ 图像处理类库CxImage源代码,CxImage是一个可以用于MFC 的C++类,可以打开,保存,显示,转换各种格式的图像文件,比如BMP, JPEG, GIF, PNG, TIFF, ...

  10. Java面试准备十六:数据库——MySQL性能优化

    2017年04月20日 13:09:43 阅读数:6837 这里只是为了记录,由于自身水平实在不怎么样,难免错误百出,有错的地方还望大家多多指出,谢谢. 来自MySQL性能优化的最佳20+经验 为查询 ...