QSemaphore生产者消费者问题

时间:2011-09-02 01:11:15

标签: qt

这或多或少是Qt的例子,有一些小变化。

输出为PcPcPcPc ......等。我不明白为什么。

即,我对sProducer.acquire(256)如何感到困惑;作品。我相信我理解sProducer.acquire(1);作品。获取超过1的任何东西对我来说没有意义,因为我没有看到获得超过1的东西在逻辑上有什么不同。有人可以解释一下吗?从表面上看,由于信号量开销,写入1个字节并读取1个字节似乎效率不高......但获取更多资源似乎不会产生性能差异,代码也没有意义。

逻辑上我认为获取和发布必须具有相同的数字(无论该数字是多少)。但是如何修改这段代码以便我可以获得更多(比如256),从而减少信号量开销?当获取和释放不是1时,代码对我来说没有意义。

#include <QtCore>
#include <iostream>
#include <QTextStream>

//Global variables.
QTextStream out(stdout);
QTextStream in(stdin);

const int DataSize = 1024; 
const int BufferSize = 512;
char buffer[BufferSize];    

QSemaphore sProducer(BufferSize);
QSemaphore sConsumer(0);
//-----------------------------

class Producer : public QThread
{
public:
    void run();
};

void Producer::run()
{
    for (int i = 0; i < DataSize; ++i) {
        sProducer.acquire(256);
        buffer[i % BufferSize] = 'P';
        sConsumer.release(256);
    }
}

class Consumer : public QThread
{
public:
    void run();
};

void Consumer::run()
{
    for (int i = 0; i < DataSize; ++i) {
        sConsumer.acquire(256);
        std::cerr << buffer[i % BufferSize];
        out << "c";
        out.flush();
        sProducer.release(256);
    }
    std::cerr << std::endl;
}

int main()
{
    Producer producer;
    Consumer consumer;
    producer.start();
    consumer.start();
    producer.wait();
    consumer.wait();

    in.readLine();  //so i can read console text.
    return 0;
}

1 个答案:

答案 0 :(得分:0)

由于只有一个生产者和一个消费者,他们可以自由移动他们自己的私有光标,即他们想要的字节数的i变量,只要有足够的空间去做(某事)使用512缓冲区两侧256以上会导致死锁。

基本上,当一个线程成功获取256个字节时,这意味着它可以在一次操作中安全地读取或写入这256个字节,因此您只需在获取/释放块中放置另一个循环来处理该字节数。

对于制作人:

void Producer::run()
{
    for (int i = 0; i < DataSize; ++i) {
        const int blockSize = 256;
        sProducer.acquire(blockSize);
        for(int j = 0; j < blockSize; ++i, ++j) {
            buffer[i % BufferSize] = 'P';
        }
        sConsumer.release(blockSize);
    }
}

对消费者而言

void Consumer::run()
{
    for (int i = 0; i < DataSize; ++i) {
        const int blockSize = 128;
        sConsumer.acquire(blockSize);
        for(int j = 0; j < blockSize; ++i, ++j) {
            std::cerr << buffer[i % BufferSize];
            out << "c";
            out.flush();
        }
        sProducer.release(blockSize);
    }
    std::cerr << std::endl;
}
相关问题