QSemaphore、QWaitCondition实现线程同步

来源:互联网 发布:mysql 高性能集群 编辑:程序博客网 时间:2024/06/05 05:04

    示例程序来自Qt5.4\Examples\Qt-5.4\corelib\threads,做出一定的注解更容易理解,详细解析推荐参考Qt手册Semaphores Example、Wait Conditions Example

1. Semaphores Example

SOURCES += semaphores.cppQT = coreCONFIG -= app_bundleCONFIG += console# installtarget.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/semaphoresINSTALLS += target
#include <QtCore>#include <stdio.h>#include <stdlib.h>//! [0]const int DataSize = 10;const int BufferSize = 6;char buffer[BufferSize];QSemaphore freeBytes(BufferSize);QSemaphore usedBytes;class Producer : public QThread{public:    void run() Q_DECL_OVERRIDE    {        qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));        for (int i = 0; i < DataSize; ++i) {            freeBytes.acquire(); // -1, 用掉一个空闲字节,最大只有6个空闲字节,初始为6,如果获取失败了,那就等着消费者线程读完后释放资源            buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4];            qDebug("+");            usedBytes.release();  // +1, 释放了一个资源,也就是产生了一个字节数据,消费者可以读取        }    }};class Consumer : public QThread{    Q_OBJECTpublic:    void run() Q_DECL_OVERRIDE    {        for (int i = 0; i < DataSize; ++i)        {            usedBytes.acquire(); // -1, 获取生产者线程产生的资源,获取资源不成功,那就阻塞在这里,直到生产者产生新数据            fprintf(stdout, "%c", buffer[i % BufferSize]);            freeBytes.release();  //+1, 数据读取(消费)完毕,释放了一个空闲资源        }        fprintf(stderr, "\n");    }signals:    void stringConsumed(const QString &text);protected:    bool finish;};int main(int argc, char *argv[]){    QCoreApplication app(argc, argv);    Producer producer;    Consumer consumer;    producer.start();    consumer.start();    producer.wait();    consumer.wait();    return 0;}#include "semaphores.moc"
2.
Wait Conditions Example

QT = coreCONFIG -= moc app_bundleCONFIG += consoleSOURCES += waitconditions.cpp# installtarget.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/waitconditionsINSTALLS += target
#include <QtCore>#include <stdio.h>#include <stdlib.h>const int DataSize = 100000;const int BufferSize = 8192;char buffer[BufferSize];QWaitCondition bufferNotEmpty;QWaitCondition bufferNotFull;QMutex mutex;int numUsedBytes = 0;class Producer : public QThread{public:    Producer(QObject *parent = NULL) : QThread(parent)    {    }    void run() Q_DECL_OVERRIDE    {        qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));        for (int i = 0; i < DataSize; ++i) {            mutex.lock();            if (numUsedBytes == BufferSize)                bufferNotFull.wait(&mutex);            mutex.unlock();            buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4];            mutex.lock();            ++numUsedBytes;            bufferNotEmpty.wakeAll();            mutex.unlock();        }    }};class Consumer : public QThread{    Q_OBJECTpublic:    Consumer(QObject *parent = NULL) : QThread(parent)    {    }    void run() Q_DECL_OVERRIDE    {        for (int i = 0; i < DataSize; ++i) {            mutex.lock();            if (numUsedBytes == 0)                bufferNotEmpty.wait(&mutex);            mutex.unlock();            fprintf(stderr, "%c", buffer[i % BufferSize]);            mutex.lock();            --numUsedBytes;            bufferNotFull.wakeAll();            mutex.unlock();        }        fprintf(stderr, "\n");    }signals:    void stringConsumed(const QString &text);};int main(int argc, char *argv[]){    QCoreApplication app(argc, argv);    Producer producer;    Consumer consumer;    producer.start();    consumer.start();    producer.wait();    consumer.wait();    return 0;}#include "waitconditions.moc"






原创粉丝点击