C++/Qt/QThread

Материал из C\C++ эксперт
Перейти к: навигация, поиск

Extends QThread to create thread

<source lang="cpp">

Foundations of Qt Development\Chapter12\inorderthreads\main.cpp /*

* Copyright (c) 2006-2007, Johan Thelin
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
* 
*     * Redistributions of source code must retain the above copyright notice, 
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice,  
*       this list of conditions and the following disclaimer in the documentation 
*       and/or other materials provided with the distribution.
*     * Neither the name of APress nor the names of its contributors 
*       may be used to endorse or promote products derived from this software 
*       without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
  1. include <QApplication>
  2. include <QThread>
  3. include <QMutex>
  4. include <QMessageBox>
  5. include <QtDebug>

class TextThread : public QThread { public:

 TextThread( QString text );
 
 void run();
 

private:

 QString m_text;

}; bool stopThreads = false; TextThread::TextThread( QString text ) : QThread() {

 m_text = text;

} QMutex mutex; void TextThread::run() {

 while( !stopThreads )
 {
   mutex.lock();
   if( stopThreads )
     return;
     
   qDebug() << m_text;
   sleep( 1 );
   mutex.unlock();
 }

} int main( int argc, char **argv ) {

 QApplication app( argc, argv );
 
 TextThread foo( "Foo" ), bar( "Bar" );
 
 foo.start();
 bar.start();
 
 QMessageBox::information( 0, "Threading", "Close me to stop!" );
 
 stopThreads = true;
 
 foo.wait();
 bar.wait();
   
 return 0;

}


 </source>


Producer and consumer by Qt thread

<source lang="cpp">

Foundations of Qt Development\Chapter12\competingsemaphore\main.cpp /*

* Copyright (c) 2006-2007, Johan Thelin
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
* 
*     * Redistributions of source code must retain the above copyright notice, 
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice,  
*       this list of conditions and the following disclaimer in the documentation 
*       and/or other materials provided with the distribution.
*     * Neither the name of APress nor the names of its contributors 
*       may be used to endorse or promote products derived from this software 
*       without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
  1. include <QApplication>
  2. include <QThread>
  3. include <QSemaphore>
  4. include <QMutex>
  5. include <QtDebug>

const int bufferSize = 20; QChar buffer[ bufferSize ]; QSemaphore freeSpace( bufferSize ); QSemaphore availableData( 0 ); QSemaphore atEnd( 0 ); class TextProducer : public QThread { public:

 TextProducer( QString text );
 
 void run();
 

private:

 QString m_text;

}; TextProducer::TextProducer( QString text ) : QThread() {

 atEnd.release();
 m_text = text;

} void TextProducer::run() {

 static int index = 0;
 static QMutex indexMutex;
 
 for( int i=0; i<m_text.length(); ++i )
 {
   freeSpace.acquire();
   indexMutex.lock();
   buffer[ index++ % bufferSize ] = m_text.data()[ i ];
   indexMutex.unlock();
   
   if( i == m_text.length()-1 )
     atEnd.acquire();
     
   availableData.release();
 }

} class TextConsumer : public QThread { public:

 void run();

}; void TextConsumer::run() {

 int i = 0;
 
 while( atEnd.available() || availableData.available() )
 {
   availableData.acquire();
   qDebug() << buffer[ i ];
   i = (i+1) % bufferSize;
   freeSpace.release();
 }

} int main( int argc, char **argv ) {

 QApplication app( argc, argv );
 
 TextProducer p1( "this text is written using lower case characters."
   "it will compete with a text written using upper case characters." );
 TextProducer p2( "THIS TEXT IS WRITTEN USING UPPER CASE CHARACTERS!"
   "IT WILL COMPETE WITH A TEXT WRITTEN USING LOWER CASE CHARACTERS!" );
 TextConsumer consumer;
 
 p1.start();
 p2.start();
 consumer.start();
 
 p1.wait();
 p2.wait();
 consumer.wait();
   
 return 0;

}


 </source>


Thread sleeps

<source lang="cpp"> Foundations of Qt Development\Chapter12\simplethreads\main.cpp /*

* Copyright (c) 2006-2007, Johan Thelin
* 
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
* 
*     * Redistributions of source code must retain the above copyright notice, 
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice,  
*       this list of conditions and the following disclaimer in the documentation 
*       and/or other materials provided with the distribution.
*     * Neither the name of APress nor the names of its contributors 
*       may be used to endorse or promote products derived from this software 
*       without specific prior written permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
  1. include <QApplication>
  2. include <QThread>
  3. include <QMessageBox>
  4. include <QtDebug>

class TextThread : public QThread { public:

 TextThread( QString text );
 
 void run();
 

private:

 QString m_text;

}; bool stopThreads = false; TextThread::TextThread( QString text ) : QThread() {

 m_text = text;

} void TextThread::run() {

 while( !stopThreads )
 {
   qDebug() << m_text;
   sleep( 1 );
 }

} int main( int argc, char **argv ) {

 QApplication app( argc, argv );
 
 TextThread foo( "Foo" ), bar( "Bar" );
 
 foo.start();
 bar.start();
 
 QMessageBox::information( 0, "Threading", "Close me to stop!" );
 
 stopThreads = true;
 
 foo.wait();
 bar.wait();
   
 return 0;

}


 </source>


Using QThread

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the documentation of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.0 as published by the Free Software
    • Foundation and appearing in the file LICENSE.GPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. include <QThread>

class MyThread : public QThread {

   Q_OBJECT

protected:

   void run();

};


  1. include <QCache>
  2. include <QMutex>
  3. include <QThreadStorage>
  4. include "threads.h"

void MyThread::run()

{

}

  1. define Counter ReentrantCounter

class Counter

{ public:

   Counter() { n = 0; }
   void increment() { ++n; }
   void decrement() { --n; }
   int value() const { return n; }

private:

   int n;

};

  1. undef Counter
  2. define Counter ThreadSafeCounter

class Counter

{ public:

   Counter() { n = 0; }
   void increment() { QMutexLocker locker(&mutex); ++n; }
   void decrement() { QMutexLocker locker(&mutex); --n; }
   int value() const { QMutexLocker locker(&mutex); return n; }

private:

   mutable QMutex mutex;
   int n;

};

typedef int SomeClass;

QThreadStorage<QCache<QString, SomeClass> *> caches; void cacheObject(const QString &key, SomeClass *object)

{

   if (!caches.hasLocalData())
       caches.setLocalData(new QCache<QString, SomeClass>);
   caches.localData()->insert(key, object);

} void removeFromCache(const QString &key)

{

   if (!caches.hasLocalData())
       return;
   caches.localData()->remove(key);

}

int main() {

   return 0;

}


 </source>


Wait condition

<source lang="cpp"> /****************************************************************************

    • Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    • All rights reserved.
    • Contact: Nokia Corporation (qt-info@nokia.com)
    • This file is part of the examples of the Qt Toolkit.
    • $QT_BEGIN_LICENSE:LGPL$
    • Commercial Usage
    • Licensees holding valid Qt Commercial licenses may use this file in
    • accordance with the Qt Commercial License Agreement provided with the
    • Software or, alternatively, in accordance with the terms contained in
    • a written agreement between you and Nokia.
    • GNU Lesser General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU Lesser
    • General Public License version 2.1 as published by the Free Software
    • Foundation and appearing in the file LICENSE.LGPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU Lesser General Public License version 2.1 requirements
    • will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    • In addition, as a special exception, Nokia gives you certain additional
    • rights. These rights are described in the Nokia Qt LGPL Exception
    • version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    • GNU General Public License Usage
    • Alternatively, this file may be used under the terms of the GNU
    • General Public License version 3.0 as published by the Free Software
    • Foundation and appearing in the file LICENSE.GPL included in the
    • packaging of this file. Please review the following information to
    • ensure the GNU General Public License version 3.0 requirements will be
    • met: http://www.gnu.org/copyleft/gpl.html.
    • If you have questions regarding the use of this file, please contact
    • Nokia at qt-info@nokia.com.
    • $QT_END_LICENSE$
                                                                                                                                                        • /
  1. include <QtCore>
  2. include <stdio.h>
  3. 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:

   void run();

}; void Producer::run() {

   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

{ public:

   void run();

}; void Consumer::run() {

   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");

}

int main(int argc, char *argv[])

{

   QCoreApplication app(argc, argv);
   Producer producer;
   Consumer consumer;
   producer.start();
   consumer.start();
   producer.wait();
   consumer.wait();
   return 0;

}


 </source>