【linux高级程序设计】(第十二章)Linux多线程编程 3
条件变量通信机制
条件变量必须配合互斥锁一起实现对资源的互斥访问
使用方法:
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的更多相关文章
- linux高级管理第十二章--rsync
实验部分 1.安装rsync 2.配置文件 3.配置密码 4.后续 5.为了测试,创建几个文件 配置实时同步 1.调整inotify内核参数 安装inotify-tools 测试同步 编写脚本 验证 ...
- 读书笔记 - js高级程序设计 - 第十二章 DOM2和DOM3
Node类型的变化 访问元素的样式 myDiv.style.backgroundColor = "red" myDiv.style.width = "100px& ...
- 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条
http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程 ...
- 鸟哥的linux私房菜——第十二章学习(Shell Scripts)
第十二章 Shell Scripts 1.0).什么是shell scripts? script 是"脚本.剧本"的意思.整句话是说, shell script 是针对 shel ...
- 读书笔记 - js高级程序设计 - 第十五章 使用Canvas绘图
读书笔记 - js高级程序设计 - 第十三章 事件 canvas 具备绘图能力的2D上下文 及文本API 很多浏览器对WebGL的3D上下文支持还不够好 有时候即使浏览器支持,操作系统如果缺缺 ...
- 鸟哥的Linux私房菜——第十二章:档案的压缩与打包
视频链接: 土豆:http://www.tudou.com/programs/view/GncwT0FJKsQ B站(推荐):http://www.bilibili.com/video/av98857 ...
- 第三十二章 Linux常规练习题(一)
一.练习题一 1.超级用户(管理员用户)提示符是____,普通用户提示符是____.2.linux关机重启的命令有哪些 ?3.bash是什么?4.bash特性, 常见的bash特性有哪些?5.网卡的配 ...
- 第十二章 Linux三剑客之老三—grep
一.Linux grep 命令用于查找文件里符合条件的字符串. Linux系统中的grep命令是一种功能强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.grep全称是Global ...
- 【linux高级程序设计】(第九章)进程间通信-管道 1
Linux操作系统所支持的主要进程间的通信机制. 无名管道 PIPE cat test.txt| grep hello 上面这种管道,将一个命令的输出作为另一个命令的输入,而这种管道是临时的,命令执行 ...
- 第十二章Linux文件系统与日志
1.inode 包含文件的元信息(1)inode 内容:文件的字节数.拥有者的 UID.GID.文件的读写执行权限.时间戳等,但不包含文件名.文件名是储存在目录的目录项中.(2)查看文件的 inode ...
随机推荐
- Android 自定义圆形图片 CircleImageView
1.效果预览 1.1.布局中写自定义圆形图片的路径即可 1.2.然后看一看图片效果 1.3.原图是这样的 @mipmap/ic_launcher 2.使用过程 2.1.CircleImageView源 ...
- 关于 package.json 和 package-lock.json 文件说明
package.json 在 Node.js 中,模块是一个库或框架,也是一个 Node.js 项目.Node.js 项目遵循模块化的架构,当我们创建了一个 Node.js 项目,意味着创建了一个模块 ...
- python的高阶函数与匿名函数
一.高阶函数的定义 高阶函数:就是把函数当成参数传递的一种函数,例如: def add(x,y,f): return f(x)+f(y) print(add(-8,11,abs) 结果:19 解释: ...
- HTML标准开头
<!doctype html> <html> <head> <meta charset="utf-8"> <title&g ...
- javascript类式继承模式#3——借用和设置原型
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 通过广播关闭应用程序(每个Activity)和连续点击两次返回键关闭应用程序
对于一个应用程序可能有很多个Activity,可能每个人并不想一个个的去关闭Activity,也有可能忘了,那怎么关闭所有的未关闭的Activity呢,其实有很多方法,但是我最喜欢的一种就是通过广播事 ...
- Python 协程与事件循环
Table of Contents 前言 协程 async & await 事件循环 asyncio 的事件循环 结语 参考链接 前言 Python 标准库 asyncio 是我目前接触过的最 ...
- day06_08 字符串
1.0 双引号和单引号的区别 a = "Let's go" print(a) #>>>Let's go 2.0 重复输出字符串* print('hello'*2) ...
- leetcode_day02
任务二:删除排序数组中的重复项 原文链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/ 最开始的解决思路: ...
- DB2数据库的日志文件管理
DB2数据库的日志文件管理 DB2的日志模式 1.1循环日志 当循环日志生效时,事务数据将通过循环的方式写入主要日志文件.当存储于某个日志文件中的所有记录都不再需要用于恢复时,该日志文件将被重用,并且 ...