【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 = 0;
    prod->writepos = 0;
}

//在缓冲区输入一个数据
void put(struct prodcons * prod, int data)
{
    //锁定互斥锁
    pthread_mutex_lock(&prod->lock);
    while((prod->writepos + 1) % 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 = 0;
    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 = 0;
    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 = 1; n <= 5; n++) //生产5个产品
    {
        printf("producer sleep 1 second...\n");
        sleep(1);
        printf("put the %d product\n", n);
        put(&buffer, n);
    }
    for(n = 6; n <= 10; n++)
    {
        printf("producer sleep 3 second...\n");
        sleep(3);
        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 = 0;
    while(1)
    {
        printf("consumer sleep 2 second...\n");
        sleep(2);
        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, 0);
    pthread_create(&th_b, NULL, consumer, 0);
    pthread_join(th_a, &retval);
    pthread_join(th_b, &retval);
    return 0;
}

验证,可用

时间: 2024-12-09 06:51:40

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

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

Node类型的变化   访问元素的样式 myDiv.style.backgroundColor = "red" myDiv.style.width = "100px" 计算的样式 记住所有计算的样式都是只读的 偏移量 offsetHeight 外边框外 offsetWidth offsetLeft  外边框外 到 左端 offsetTop  客户区的大小 clientWidth  内边框外缘 clientHeight 内边框外缘 滚动大小 scrollHeight

Linux与云计算——第二阶段Linux服务器架设 第一十二章:数据库搭建—PostgreSQL

Linux与云计算--第二阶段Linux服务器架设 第一十二章:数据库搭建-PostgreSQL 1.1 安装PostgreSQL [1] 安装并启动PostgreSQL. [[email protected] ~]# yum -y install postgresql-server [[email protected] ~]# postgresql-setup initdb Initializing database ... OK [[email protected] ~]# vim /var

第二十二章 Linux文件比较,文本文件的交集、差集与求差:comm命令

第二十二章 Linux文件比较,文本文件的交集.差集与求差:comm命令 名词解释 comm 命令 可以用于两个文件之间的比较,它有一些选项可以用来调整输出,以便执行交集.求差.差集操作. 交集:打印两个文件所共有的行 求差:打印出指定文件所包含的其不相同的行. 差集:打印出包含在一个文件中,但不包含在其他指定文件中的行. 语法 comm(选项)(参数) 选项 -1 :不显示在第一个文件出现的内容: -2 :不显示在第二个文件中出现的内容: -3 :不显示同时在两个文件中都出现的内容. ? 参数

javascript高级程序设计 第十四章--表单脚本

javascript高级程序设计 第十四章--表单脚本 在HTML中表单由<form>元素表示,在js中表单对应的是HTMLFormElement类型,这个类型也有很多属性和方法:取得表单元素的引用还是为它添加id特性,用DOM操作来获取表单元素:提交表单:把<input>或<button>元素的type特性设置为"submit",图像按钮把<input>元素的type特性设置为"image",也可以调用submit(

Java学习笔记—第十二章 Java网络编程入门

第十二章  Java网络编程入门 Java提供的三大类网络功能: (1)URL和URLConnection:三大类中最高级的一种,通过URL网络资源表达方式,可以很容易确定网络上数据的位置.利用URL的表示和建立,Java程序可以直接读入网络上所放的数据,或把自己的数据传送到网络的另一端. (2)Socket:又称"套接字",用于描述IP地址和端口(在Internet中,网络中的每台主机都有一个唯一的IP地址,而每台主机又通过提供多个不同端口来提供多种服务).在客户/服务器网络中,当客

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

http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程java任务timerstring 2009-01-16 21:12 6722人阅读 评论(0) 收藏 举报  分类: J2SE(63)  版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天讲了Swing基本的控件,今天开始讲特殊控件.一天讲2个吧,首先讲用JProgressBar,Pro

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

读书笔记 - js高级程序设计 - 第十三章 事件 canvas 具备绘图能力的2D上下文 及文本API 很多浏览器对WebGL的3D上下文支持还不够好 有时候即使浏览器支持,操作系统如果缺缺乏必要的绘图驱动程序,则浏览器即使支持了也没用   <canvas> var drawing = document.getElementById("drawing"); if( drawing.getContext ){ drawing.getContext("2d"

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

视频链接: 土豆: B站(推荐): 本章目录: 1. 压缩档案的用途与技术: (为啥要压缩嘞?因为比如存储一个数字1,前7位补充0浪费,压缩技术就是把空的那些用上,省硬盘空间,下载的时候也省带宽)2. Linux 系统常见的压缩指令:2.1 compress (这个是最老的压缩指令,现在不怎么用了)2.2 gzip, zcat (新一代的压缩指令,代替了compress,zcat是读取gzip和compress的压缩数据的指令)2.3 bzip2, bzcat   (bzip2更高效,压缩比高,

第十二章 linux磁盘管理-lvm(2)

yum install lvm2-2.02.72-8.el6_0.4.x86_64 1.将新创建的两个分区/dev/sdb1 /dev/sdb2转化成物理卷,主要是添加LVM属性信息并划分PE存储单元. pvcreate /dev/sdb1 /dev/sdb2 pvs pvdisplay 2.创建卷组 vgdata ,并将刚才创建好的两个物理卷加入该卷组.可以看出默认PE大小为4MB,PE是卷组的最小存储单元.可以通过 –s参数修改大小 vgcreate vgdata /dev/sdb1 /de

第十二章 &nbsp; Linux &nbsp; DNS域名解析

实验要求: n 主域名服务器地址为ns1.benet.com (173.16.16.5) n 从域名服务器地址为ns2.benet.com(173.16.16.6) n 为benet.com.accp.com区域提供以下解析记录. l Mail.benet.com(123.45.67.89).ftp.benet.com(123.45.67.90) l www.benet.com(123.45.67.88).*.benet.com(123.45.67.88) l www.accp.com (58.