zoukankan      html  css  js  c++  java
  • 对生产者和消费者问题的另一个解决办法是使用QWaitCondition(封装好了wakeOne,wakeAll,而且与QReadWriteLock对接,几乎是万能的办法)

    对生产者和消费者问题的另一个解决办法是使用QWaitCondition,它允许线程在一定条件下唤醒其他线程。其中wakeOne()函数在条件满足时随机唤醒一个等待线程,而wakeAll()函数则在条件满足时唤醒所有等待线程。

    1、bool wait (QMutex * mutex,unsigned long time = ULONG_MAX)
    1) 释放锁定的mutex
     2) 在线程对象上等待

             mutex必须由调用线程进行初锁定 。注意调用wait的话,会自动调用unlock解锁之前锁住的资源,不然会造成死锁。线程1等待线程2来改变共享资源,从而达到一定的条件然后发出信号,使得线程1从wait中的阻塞状态中被唤醒。但是线程2想改变资源,却无法办到,因为线程1调用lock之后就在wait中blocking,了但是没有及时的unlock,那么这就构成了死锁的条件。所以说wait函数除了使调用线程切换到内核态之外,还自动unlock(&mutex)。

    2、void wakeOne ()
          这将会唤醒所有等待QWaitCondition的线程。这些线程被唤醒的顺序依赖于操组系统的调度策略,并且不能被控制或预知。

    3、void wakeAll ()

           这将会唤醒所有等待QWaitCondition的线程中的一个线程。这个被唤醒的线程依赖于操组系统的调度策略,并且不能被控制或预知。

      下面通过一个典型用例:生产者和消费者,来实现这二者之间的同步。整个工程就一个main.cpp,文件如下:

    复制代码
    #include <QtCore/QCoreApplication>
    #include <QWaitCondition>
    #include <QThread>
    #include <QMutex>
    #include <iostream>
    
    const int DataSize = 100;
    const int BufferSize = 1;
    char buffer[BufferSize];
    
    QWaitCondition bufferIsNotFull;
    QWaitCondition bufferIsNotEmpty;
    QMutex mutex;
    int usedSpace  = 0;
    
    class Producer : public QThread
    {
    protected:
        void run()
        {
            for (int i = 0; i < DataSize; ++i)
            {
                mutex.lock();
                while (usedSpace == BufferSize)
                {
                    bufferIsNotFull.wait(&mutex);
                }
                std::cerr<<"P";
                ++usedSpace;
                bufferIsNotEmpty.wakeAll();
                mutex.unlock();
            }
        }
    };
    
    class Consumer : public QThread
    {
    protected:
        void run()
        {
            for (int i = 0; i < DataSize; ++i)
            {
                mutex.lock();
                while (usedSpace == 0)
                {
                    bufferIsNotEmpty.wait(&mutex);
                }
                std::cerr<<"C";
                --usedSpace;
                bufferIsNotFull.wakeAll();
                mutex.unlock();
            }
            std::cerr<<std::endl;
        }
    };
    
    int main(int argc, char *argv[])
    {
       Producer producer;
       Consumer consumer;
       producer.start();
       consumer.start();
       producer.wait();
       consumer.wait();
    return 0;
    }

    https://blog.csdn.net/skc361/article/details/19409527
  • 相关阅读:
    orleans 的一种模式
    在.net4的环境下使用Microsoft.AspNet.SignalR.Client 2.4.0
    微信卡券领用的附加测试
    SVN忽略本地文件不提交,同时不删除服务器上的文件
    SQL Server 2017安装错误:Polybase要求安装Oracle JRE 7更新51或更高版本的两种解决方法
    SQL Server遍历表(临时表)
    无法确定条件表达式的类型,因为“DateTime”和“<null>”之间没有隐式转换|Nullable类型问题与?:条件运算符
    C# 反射获取对象的内容
    c# 计算执行时间,性能,运行时间Stopwatch
    JS,JQuery循环数组,循环对象生成需要的数据
  • 原文地址:https://www.cnblogs.com/findumars/p/9085567.html
Copyright © 2011-2022 走看看