Doc: Clean up threading examples

- Example 3 (Clock) is a collection of anti-patterns.
    - It implements a slot in a QThread subclass and then forces the new
      thread to use Qt::DirectConnection to invoke the slot in the
      "wrong" thread.
    - It talks about getting away with non-thread-safe usage
    - It uses a thread as a timer and then admits that it's an over-
      complicated approach.
- Example 4 (Permanent Thread) is over-complicated yet incomplete. A
  better one exists in the QThread class ref.
- Example 1 (Thread Pool) is covered by the QThreadPool class ref.
- Example 2 (QtConcurrent::run()) is covered in the "Threading and
  Concurrent Programming Examples" page and the "QtConcurrentRun" page.
- The undocumented "Hello Thread" example is covered in the QThread
  class ref.
- These examples cannot be accessed from Qt Creator's Examples tool.
- These examples are neither widget-related nor tutorials, contrary to
  their source paths.

Task-number: QTBUG-33360
Change-Id: Ic79cb764ee925ddbcbeafee8e1d01db7fe0f6cfe
Reviewed-by: Topi Reiniö <topi.reinio@digia.com>
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
This commit is contained in:
Sze Howe Koh 2013-11-02 10:13:45 +08:00 committed by The Qt Project
parent a8351096db
commit 6b8e866391
22 changed files with 4 additions and 1067 deletions

View File

@ -1,10 +0,0 @@
QT += widgets
CONFIG += console
TEMPLATE = app
SOURCES += main.cpp \
clockthread.cpp
HEADERS += clockthread.h
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tutorials/threads/clock
INSTALLS += target

View File

@ -1,66 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtWidgets>
#include "clockthread.h"
//This class starts another thread where it emits a signal for every new second.
//! [1]
// clock/clockthread.cpp
void ClockThread::run()
{
QTimer timer;
connect(&timer, SIGNAL(timeout()), this, SLOT(timerHit()), Qt::DirectConnection);
timer.setInterval(10);
timer.start(); // puts one event in the threads event queue
exec();
timer.stop();
}
void ClockThread::timerHit()
{
QString newTime= QDateTime::currentDateTime().toString("ddd MMMM d yy, hh:mm:ss");
if(m_lastTime != newTime ){
m_lastTime = newTime;
emit sendTime(newTime) ;
}
}
//! [1]

View File

@ -1,64 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef CLOCKTHREAD_H
#define CLOCKTHREAD_H
#include <QString>
#include <QThread>
//! [1]
// clock/clockthread.h
class ClockThread : public QThread
{
Q_OBJECT
signals:
void sendTime(QString time);
private:
void run();
QString m_lastTime;
private slots:
void timerHit();
};
//! [1]
#endif // CLOCKTHREAD_H

View File

@ -1,67 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtWidgets>
#include "clockthread.h"
//A clock that does time formatting in another thread
//! [1]
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// build gui
QWidget widget;
QLabel *label = new QLabel;
QHBoxLayout *layout = new QHBoxLayout(&widget);
layout->addWidget(label);
widget.setWindowTitle("clock");
//instantiate thread object
ClockThread clockThread;
QObject::connect(&clockThread, SIGNAL(sendTime(QString)), label, SLOT(setText(QString)), Qt::QueuedConnection);
clockThread.start();
widget.show();
app.exec();
clockThread.quit();
clockThread.wait();
return 0;
}
//! [1]

View File

@ -1,63 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore>
#include <QtConcurrent>
/*
says hello from main thread and secondary thread using QtConcurrent
*/
//! [1]
// helloconcurrent/main.cpp
void hello()
{
qDebug() << "Hello from thread " << QThread::currentThread();
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QFuture<void> future = QtConcurrent::run(hello);
qDebug() << "hello from GUI thread " << QThread::currentThread();
future.waitForFinished();
return 0;
}
//! [1]

View File

@ -1,14 +0,0 @@
QT -= gui
QT += concurrent
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += helloconcurrent.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tutorials/threads/helloconcurrent
INSTALLS += target

View File

@ -1,50 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QDebug>
#include "hellothread.h"
/*
* demonstrates use of QThread, says hello in another thread and terminates
*/
void HelloThread::run()
{
qDebug() << "hello from worker thread " << thread()->currentThreadId();
}

View File

@ -1,53 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef HELLOTHREAD_H
#define HELLOTHREAD_H
#include <QThread>
class HelloThread : public QThread
{
Q_OBJECT
private:
void run();
};
#endif // HELLOTHREAD_H

View File

@ -1,14 +0,0 @@
QT -= gui
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
hellothread.cpp
HEADERS += hellothread.h
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tutorials/threads/hellothread
INSTALLS += target

View File

@ -1,52 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore>
#include "hellothread.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
HelloThread thread;
thread.start();
qDebug() << "hello from GUI thread " << app.thread()->currentThreadId();
thread.wait(); // do not exit before the thread is completed!
return 0;
}

View File

@ -1,65 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore>
// A hello world program to demonstrate the use of the global thread pool
//! [1]
// hellothreadpool/main.cpp
class Work : public QRunnable
{
public:
void run()
{
qDebug() << "Hello from thread " << QThread::currentThread();
}
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
Work work;
work.setAutoDelete(false);
QThreadPool *threadPool = QThreadPool::globalInstance();
threadPool->start(&work);
qDebug() << "hello from GUI thread " << QThread::currentThread();
threadPool->waitForDone();
return 0;
}
//! [1]

View File

@ -1,14 +0,0 @@
QT -= gui
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += hellothreadpool.cpp
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tutorials/threads/hellothreadpool
INSTALLS += target

View File

@ -1,69 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore>
#include "workerobject.h"
#include "thread.h"
/*
* moves a class derived from QObject (WorkerObject) to another thread
* and calls methods over thread boundaries.
*/
//![1]
// movedobject/main.cpp
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
Thread thread;
qDebug() << "main thread ID: " << app.thread()->currentThreadId();
WorkerObject *worker = new WorkerObject;
thread.launchWorker(worker);
QMetaObject::invokeMethod(worker, "doWork", Qt::QueuedConnection);
QMetaObject::invokeMethod(worker, "startPolling", Qt::QueuedConnection, Q_ARG(int, 500));
//let application produce output for 3 seconds and quit
QTimer::singleShot(3000, &app, SLOT(quit()));
app.exec();
thread.stop();
thread.wait();
delete worker;
return 0;
}
//![1]

View File

@ -1,15 +0,0 @@
QT += widgets
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
workerobject.cpp \
thread.cpp
HEADERS += \
workerobject.h \
thread.h
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tutorials/threads/movedobject
INSTALLS += target

View File

@ -1,100 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "thread.h"
/*
* QThread derived class with additional capability to move a QObject to the
* new thread, to stop the thread and move the QObject back to the thread where
*it came from.
*/
Thread::Thread( QObject *parent)
: QThread (parent)
{
//we need a class that receives signals from other threads and emits a signal in response
shutDownHelper=new QSignalMapper;
shutDownHelper->setMapping(this,0);
connect(this, SIGNAL(started()), this, SLOT(setReadyStatus() ), Qt::DirectConnection);
connect(this, SIGNAL(aboutToStop()), shutDownHelper, SLOT(map()) );
}
//------------------------------------------------------
Thread::~Thread()
{
delete shutDownHelper;
}
//------------------------------------------------------
// starts thread, moves worker to this thread and blocks
void Thread::launchWorker(QObject *worker)
{
this->worker = worker;
start();
worker->moveToThread(this);
shutDownHelper->moveToThread(this);
connect(shutDownHelper, SIGNAL(mapped(int) ), this, SLOT(stopExecutor()), Qt::DirectConnection );
mutex.lock();
waitCondition.wait(&mutex);
}
//------------------------------------------------------
// puts a command to stop processing in the event queue of worker thread
void Thread::stop()
{
emit aboutToStop();
}
//------------------------------------------------------
// methods above this line should be called in gui thread context
// methods below this line are private and will be run in secondary thread context
//------------------------------------------------------
void Thread::stopExecutor() //secondary thread context
{
exit();
}
//------------------------------------------------------
void Thread::setReadyStatus()
{
waitCondition.wakeAll();
}

View File

@ -1,67 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef THREAD_H
#define THREAD_H
#include <QtCore>
class Thread :public QThread
{
Q_OBJECT
public:
Thread( QObject *parent=0);
~Thread();
void stop();
void launchWorker(QObject *worker);
private:
QObject *worker;
QSignalMapper *shutDownHelper;
QWaitCondition waitCondition;
QMutex mutex;
private slots:
void stopExecutor();
void setReadyStatus();
signals:
void aboutToStop();
};
#endif // THREAD_H

View File

@ -1,87 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore>
#include "workerobject.h"
/*
* represents an object that lives in another thread where it polls a resource
* and communicates with the gui thread
*/
WorkerObject::WorkerObject(QObject *parent)
: QObject(parent)
{
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(poll()));
}
//---------------------------------------------------------------
void WorkerObject::doWork()
{
qDebug() << "doing work in thread " << thread()->currentThreadId() ;
}
//---------------------------------------------------------------
WorkerObject::~WorkerObject()
{
qDebug() << "destruction WorkerObject in thread " << thread()->currentThreadId();
}
//---------------------------------------------------------------
void WorkerObject::startPolling(int milliseconds)
{
count=0;
timer->start(milliseconds);
}
//---------------------------------------------------------------
void WorkerObject::stopPolling()
{
timer->stop();
}
//---------------------------------------------------------------
void WorkerObject::poll()
{
qDebug() << QString("timer hit %1").arg(count);
count++;
}

View File

@ -1,64 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "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 Digia Plc and its Subsidiary(-ies) 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."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef WORKEROBJECT_H
#define WORKEROBJECT_H
#include <QtCore>
class WorkerObject : public QObject
{
Q_OBJECT
public:
explicit WorkerObject(QObject *parent = 0);
~WorkerObject();
public slots:
void doWork();
void startPolling(int milliseconds);
void stopPolling();
private slots:
void poll();
private:
QTimer *timer;
int count;
};
#endif // WORKEROBJECT_H

View File

@ -1,8 +0,0 @@
TEMPLATE = subdirs
SUBDIRS = hellothread \
hellothreadpool \
clock \
movedobject
qtHaveModule(concurrent): SUBDIRS += helloconcurrent

View File

@ -1,2 +1,2 @@
TEMPLATE = subdirs
SUBDIRS += threads addressbook widgets modelview gettingStarted
SUBDIRS += addressbook widgets modelview gettingStarted

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -219,130 +219,9 @@
\section1 Examples
This tutorial comes with examples for Qt's three basic ways of working with
threads. Two more examples show how to communicate with a running thread
and how a QObject can be placed in another thread, providing service to the
main thread.
\list
\li Using QThread as shown \l{Qt thread basics}{above}
\li \l{Example 1: Using the Thread Pool}{Using the global QThreadPool}
\li \l{Example 2: Using QtConcurrent}{Using QtConcurrent}
\li \l{Example 3: Clock}{Communication with the GUI thread}
\li \l{Example 4: A Permanent Thread}{A permanent QObject in another thread
provides service to the main thread}
\endlist
The following examples can all be compiled and run independently. The source can
be found in the examples directory: examples/tutorials/threads/
\section2 Example 1: Using the Thread Pool
Creating and destroying threads frequently can be expensive. To avoid the
cost of thread creation, a thread pool can be used. A thread pool is a
place where threads can be parked and fetched. We can write the same
"hello thread" program as \l{Qt Thread Basics}{above} using the global
thread pool. We derive a class from QRunnable. The code we want to run in
another thread needs to be placed in the reimplemented QRunnable::run()
method.
\snippet ../widgets/tutorials/threads/hellothreadpool/hellothreadpool.cpp 1
We instantiate Work in main(), locate the global thread pool and use the
QThreadPool::start() method. Now the thread pool runs our worker in another
thread. Using the thread pool has a performance advantage because threads
are not destroyed after they have finished running. They are kept in a pool
and wait to be used again later.
\section2 Example 2: Using QtConcurrent
\snippet ../widgets/tutorials/threads/helloconcurrent/helloconcurrent.cpp 1
We write a global function hello() to implement the work. QtConcurrent::run()
is used to run the function in another thread. The result is a QFuture.
QFuture provides a method called \l{QFuture::}{waitForFinished()}, which
blocks until the calculation is completed. The real power of QtConcurrent
becomes visible when data can be made available in a container. QtConcurrent
provides several functions that are able to process itemized data on all
available cores simultaneously. The use of QtConcurrent is very similar to
applying an STL algorithm to an STL container.
\l{examples-threadandconcurrent.html}{QtConcurrent Map} is a very short and
clear example about how a container of images can be scaled on all available
cores. The image scaling example uses the blocking variants of the functions
used. For every blocking function there is also a non-blocking, asynchronous
counterpart. Getting results asynchronously is implemented with QFuture and
QFutureWatcher.
\section2 Example 3: Clock
\image thread_clock.png "clock"
We want to produce a clock application. The application has a GUI and a
worker thread. The worker thread checks every 10 milliseconds what time it
is. If the formatted time has changed, the result will be sent to the GUI
thread where it is displayed.
Of course, this is an overly complicated way of designing a clock and,
actually, a separate thread is unnecessary. We would be better off placing
the timer in the main thread because the calculation made in the timer slot
is very short-lived. This example is purely for instructional use and shows
how to communicate from a worker thread to a GUI thread. Note that
communication in this direction is easy. We only need to add a signal
to QThread and make a queued signal/slot connection to the main thread.
Communication from the GUI to the worker thread is shown in the next
example.
\snippet ../widgets/tutorials/threads/clock/main.cpp 1
We've connected the \c clockThread with the label. The connection must be a
queued signal-slot connection because we want to put the call in the event
loop.
\snippet ../widgets/tutorials/threads/clock/clockthread.h 1
We have derived a class from QThread and declared the \c sendTime() signal.
\snippet ../widgets/tutorials/threads/clock/clockthread.cpp 1
The trickiest part of this example is that the timer is connected to its
slot via a direct connection. A default connection would produce a queued
signal-slot connection because the connected objects live in different
threads; remember that QThread does not live in the thread it creates.
Still it is safe to access ClockThread::timerHit() from the worker thread
because ClockThread::timerHit() is private and only touches local variables
and a private member that isn't touched by public methods.
QDateTime::currentDateTime() isn't marked as thread-safe in Qt
documentation, however we can get away with using it in this small
example because we know that the QDateTime::currentDateTime() static
method isn't used in any other threads.
\section2 Example 4: A Permanent Thread
This example shows how it is possible to have a QObject in a worker thread
that accepts requests from the GUI thread, does polling using a timer and
continuously reports results back to the GUI thread. The actual work
including the polling must be implemented in a class derived from QObject.
We have called this class \c WorkerObject in the code shown below. The
thread-specific code is hidden in a class called \c Thread, derived from
QThread.
\c Thread has two additional public members. The \c launchWorker() member
takes the worker object and moves it to another thread with a started event
loop.
The call blocks for a very short moment until the thread creation operation
is completed, allowing the worker object to be used again on the next line.
The \c Thread class's code is short but somewhat involved, so we only show
how to use the class.
\snippet ../widgets/tutorials/threads/movedobject/main.cpp 1
QMetaObject::invokeMethod() calls a slot via the event loop. The worker
object's methods should not be called directly after the object has been
moved to another thread. We let the worker thread do some work and polling,
and use a timer to shut the application down after 3 seconds. Shutting the
worker down needs some care. We call \c{Thread::stop()} to exit the event
loop. We wait for the thread to terminate and, after this has occurred, we
delete the worker.
Qt comes with several examples for using threads. See the class references
for QThread and QThreadPool for simple examples. See the \l{Threading and
Concurrent Programming Examples} page for more advanced ones.
\section1 Digging Deeper