购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.5 项目案例2:通过信号量实现生产者消费者模型

信号量(Semaphore)有时被称为信号灯,是在多线程环境下使用的一种设施,可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其他想进入该关键代码段的线程必须等待,直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。

QSemaphore 是QMutex的一般化,是特殊的线程锁,允许多个线程同时访问临界资源。信号量可以理解为对互斥量功能的扩展,互斥量只能锁定一次,而信号量可以获取多次,且可以用来保护一定数量的同种资源。acquire(n)用于获取 n 个资源,当没有足够的资源时,调用者将被阻塞直到有足够的可用资源。release(n)用于释放 n 个资源。

QSemaphore 类成员主要函数介绍如下。

● QSemaphore (int n = 0) :建立对象时可以给它 n 个资源,默认为0。

● void acquire (int n = 1) :获取1个资源。

● int available () const :返回在任意时刻可用的资源数目。

● void release (int n = 1) :释放1个资源。

● bool tryAcquire (int n = 1) :如果得不到足够的资源会立即返回。

● bool tryAcquire (int n, int timeout) :如果得不到足够的资源会等待timeout时间返回。

下面给出实现生产者消费者模型的代码。 X8D4eA+LTbcm7dT2iV7pLNRpLF6SoTcaxie2INPF2p2Zqhz4RmqGN0BaqL6wykKC

#include <QtCore/QCoreApplication>
#include <QSemaphore>//信号量头文件
#include <QThread>
#include <cstdlib>
#include <cstdio>
 
const int DataSize = 100000; //数据大小
const int BufferSize = 8192; //缓存区大小
char buffer[BufferSize];
 
QSemaphore  production(BufferSize);
QSemaphore  consumption;
 
class Producer:public QThread
{
public:
    void run();
};
 
void Producer::run()
{
    for(int i = 0; i < DataSize; i++)
    {
        production.acquire();//获取信号量
        buffer[i%BufferSize] = "ACGT"[(int)qrand()%4];//随机获取一个字母
        consumption.release();//释放信号量
    }
}
 
class Consumer:public QThread
{
public:
    void run();
 
};
 
void Consumer::run()
{
    for(int i = 0; i < DataSize; i++)
    {
        consumption.acquire();//获取信号量
        fprintf(stderr, "%c", buffer[i%BufferSize]);
        production.release();//释放信号量
    }
    fprintf(stderr, "%c", "\n");
}
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Producer productor;
    Consumer consumer;
    producer.start();
    consumer.start();
    producer.wait();
    consumer.wait();
    
    return a.exec();
}
点击中间区域
呼出菜单
上一章
目录
下一章
×