[Development] Evolving Qt's multithreading API

Robert Knight robertknight at gmail.com
Wed Feb 20 17:24:21 CET 2013


Hello,

A few thoughts:

- In general and especially for newcomers, encourage task-orientated
concurrency and avoiding shared state where possible.
This partly about documentation and the examples but also in the kind of
approach that the APIs optimize for.

- Having had the er, pleasure of debugging a number of concurrency issues
in QThread, ThreadWeaver and other third party libraries over the years, I'd
say there is a very strong case for going with a wrapper around a
well-written and tested existing library where possible.

A few years back I tended to use the 'create object, move to thread, send
messages' approach to doing background work.
The problem is that it usually isn't explicit enough when reading the code
what data a particular thread can or cannot safety access.

With cross-thread signals, you have the issue that when you emit a signal,
it isn't immediately clear at that point that you may be
sending data to another thread - depending on who happens to be listening.
If you see that a value is being written into a channel on
the other hand - as you would find in Go or Rust, it is much more explicit
that the value or reference is being passed to another thread for use.

Regards,
Rob.


On 20 February 2013 15:10, Sze Howe Koh <szehowe.koh at gmail.com> wrote:

> On 20 February 2013 22:49, André Somers <andre at familiesomers.nl> wrote:
> > Op 20-2-2013 15:45, Sze Howe Koh schreef:
> >> Hi all,
> >>
> >> Some time ago there was some talk about improving Qt's multithreading
> >> API. I'm summarizing them here to stop them from fading into
> >> obscurity, and to see if there's any interest in following them up.
> > There is also a proposal posted here:
> > http://qt-project.org/forums/viewthread/2488
> >
> > André
>
> André meant http://qt-project.org/forums/viewthread/24884/ :-)
>
> I'd like to add this idea to the mix: Give Qt's low-level API more
> flexibility and consistency.
>
> Currently, Qt's suggestions for multithreading are:
>
> - Subclass a worker QObject and move it to a basic QThread (if an
> event loop is desired)
> - Subclass QThread (if an event loop is not desired)
> - Subclass QRunnable and run it via a QThreadPool (if recycling
> QThreads is desired)
> - Call QtConcurrent::run() (if a parallel function call is desired)
> - Use QtConcurrent's filter-map-reduce API (if high-level container
> processing is desired)
>
>
> Ignoring filter-map-reduce (the only true high-level option here), the
> low-level API looks quite disparate. Furthermore, some features are
> missing:
>
> - The ability to use QRunnable, or make a parallel function call,
> without being tied to a thread pool
> - The ability to emit a signal when a thread finishes with QRunnable
> - The ability to delay a parallel function call
> - The ability to elegantly separate code control and thread logic
>
>
> === PROPOSED NEW METHODS ===
> 1) static QThread* QThread::setupSimpleThread(QRunnable *runnable);
> 2) static QThread* QThread::setupSimpleThread(Function func, Args arg,
> ...);
> 3) static QThread* QThread::setupEventLoop(QObject* worker);
>
> 4) void QThreadPool::start(Function func, Args arg, ...);
> 5) bool QThreadPool::tryStart(Function func, Args arg...);
>
>
> === BEHAVIOUR ===
> (1) binds a QRunnable to a QThread, which will call the
> QRunnable::run() when start()'ed.
> (2) binds a function and zero or more arguments to a QThread, which
> will call the function when start()'ed.
> (3) moves the worker QObject to the new thread, ready to have its
> slots invoked when the QThread is start()'ed.
> (4) and (5) are similar to (2), but it uses a recyclable thread from a
> QThreadPool and (tries to) start immediately
>
>
> === ADVANTAGES ===
> - The missing features mentioned earlier are provided
> - A symmetrical API for using both recycled and unrecycled
> threads(QThreadPool and QThread)
> - A unified, self-documenting API, which clearly distinguishes and
> enforces the 2 different ways to using QThread (both with and without
> an event loop)
> - A way to cleanly separate thread control (QThread) and threaded code
> (QRunnable), thus making it more idiot-proof. Also achieved without
> the huge overhead of the worker-object approach
>
>
> === IMPLEMENTATION ===
> (1) The QThread implementation can be similar to QThreadPoolThread,
> except that it doesn't check the number of active threads.
> (2, 4, 5) Ideally, we'd use a variadic template with std::function +
> std::bind behind the scenes. But, since C++98 support is required, I
> guess we'll have to follow QtConcurrent::run()'s approach (multiple
> overloaded templates for different numbers of arguments).
> (3) setupEventLoop() is just a simple wrapper that instantiates a
> basic QThread and calls moveToThread() on the worker, before returning
> the QThread.
>
>
>
> Thoughts?
>
> Regards,
> Sze-Howe
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20130220/abde17cf/attachment.html>


More information about the Development mailing list