专业课程设计之客户与服务器程序的同步与通信机制的设计(四)信号量

583 篇文章 127 订阅
36 篇文章 23 订阅

信号量版源码下载地址为:


http://download.csdn.net/detail/qq78442761/9862942

---------------------------------------------------------------------------------------------------------------------------------------------------------

互斥锁版源码下载地址为:

http://download.csdn.net/detail/qq78442761/9856423


---------------------------------------------------------------------------------------------------------------------------------------------------------

上一节为数据共享和线程,未读的博友请先阅读:

http://blog.csdn.net/qq78442761/article/details/72819470


---------------------------------------------------------------------------------------------------------------------------------------------------------



上一个版本里面,使用的是互斥锁。

在本博文里面,将会使用信号量进行资源同步。

下面是Qt中对信号量的解释。

如下图所示:


所有易知,信号量是互斥锁的扩展,并且是一个计数的功能。

使用acquire函数对资源进行要求(减少)。

使用release函数对资源进行发布(增加)。

下面是官方给出的例子,如下图所示:


在本程序中,我们用两个信号量,一个信号量用于生产与消费,一个信号量用于判断产品是否为满。

代码如下所示。

resource.h

#ifndef RESOURCE_H  
#define RESOURCE_H


class Resource  //资源类
{
public:        
    Resource(); 

    //编程时一般把要共享的东西设置为静态(也就是保存到静态区)(也就是临界资源)
    static int getResourceNum();    //获得资源的数量
    static void increaseResourceNum(int);   //增加资源的数量
    static void reduceResourceNum(int); //减少资源的数量
    static void changeToSomeNumber(int);    //把资源的数量直接改变成某值

    static int resourceNum; //资源的数量
};

#endif // RESOURCE_H
resource.cpp
/*
生产者和消费者实验使用信号量实现线程的同步
*/

#include "resource.h"   //包含"resource.h"
#include <QSemaphore>   //使用了信号量,也就是包含在QSemaphore这个头文件


//生产者线程和消费者线程启动后,生产者把自由空间转变成用过
//的空间,消费者再把用过的空间中的数据消费掉转变成自由空间,

QSemaphore freeSpace(10); //生产者初始拥有10个数据缓存区
QSemaphore usedSpace(0);//消费者初始使用了0个数据

int Resource::resourceNum=0;    //静态成员的初始化

Resource::Resource()    //构造函数
{

}

int Resource::getResourceNum()  //得到产品的资源数量
{
    return resourceNum; //返回资源的数量
}

void Resource::increaseResourceNum(int Num) //增加产品的数量
{
    //若生存者充满了消费者未读的数据,acquire()就会被阻塞,直到消费者开始消费这些数据
    freeSpace.acquire(Num);//获取“自由的”字节
    resourceNum+=Num;     //产品的数量加上Num个产品数量
    usedSpace.release(Num);//转换为“用过的”字节
    return;
}

void Resource::reduceResourceNum(int Num)
{
    //若buffer没有任何可读数据,acquire()就会被阻塞,直到生产者生产一些数据
    usedSpace.acquire(Num);//获取“用过的”资源,如果没有则一直阻塞,直到有资源为止
    resourceNum-=Num;//产品的数量减去上Num个产品数量
    freeSpace.release(Num);//转换为“自由的”字节
    return;
}

void Resource::changeToSomeNumber(int Num)  //改变产品的数量为某一个值
{
    resourceNum=Num;    //把变量Num的数量赋值给资源的数量
    return;
}


下面给出运行结果。因为freeSpace是10,所以当产品增加到10时会被挂起。

未运行程序如下所示:

产品增加到10后被挂起,如下图所示:



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值