[Development] Evolving Qt's multithreading API
Andre Somers
andre at familiesomers.nl
Mon Mar 4 22:00:34 CET 2013
Op 4-3-2013 21:21, Thiago Macieira schreef:
> On segunda-feira, 4 de março de 2013 17.25.35, André Somers wrote:
>> QFuture<T> runFunction(QFunction<T> then, QFunction<T> main);
>> QFuture<T> runFunction(QFuntion<void> then, QFuntion<T> main);
>> QFuture<T> runFunction(QFunction<T> main);
> I think this is going too far. If you want to chain jobs, we need a more
> complex job tracker. That's what ThreadWeaver is trying to do. But we need to
> solve a simpler problem first.
>
> And besides, you can always do:
>
> QFutureWatcher<T> w = runFunction(...);
> w.connect(&QFutureWatcher<T>::finished, []() { other function goes here });
> w.connect(&QFutureWatcher<T>::finished, w, &QObject::deleteLater);
The point is not to chain jobs. Indeed, that is what threadweaver is
doing. I am sorry if I did not make the point clear. The point is not to
create complex chains (or really: networks) of jobs. ThreadWeaver
already supports that use case. Still, I suppose you could do something
like that. The lines I wrote however were not meant as a chain, just as
different versions of the same method with a then method taking a
parameter of the type of the function, a then method without a parameter
and a call without any then argument.
The point is to get notification when a job is done in the simples way
possible. Nothing more, nothing less, without having to check the status
of the future. The way I understand QtConcurrent, the work is started
immediately and may finish at any moment. So, by the time I create the
QFutureWatcher and added the connect, the work may already be done.
Right? That means that you have to check for that as well, or you risk
missing the finished signal. See the discussion on the trampoline object
elsewhere in this thread. You'd avoid that by passing what you want
happening directly to the invocation to QtConcurrent.
The resulting code using a then argument would be much simpler than what
you post above. I don't quite get that code at all, by the way. You seem
to be creating a QFutureWatcher on the stack, and still connecting to
its deleteLater method? Also, which method directly returns a
QFutureWatcher? The QtConcurrent I'm familiar with returns a QFuture<T>,
which you can assign to a QFutureWatcher.
I think the proposed API addition is actually quite natural. It is not
without precedent (QTimer::singleShot()), and would result in quite
simple, readable code. It also doesn't create big constraints on the
type of object returned from these functions: there is no need for them
to be QObjects themselves.
If you want more control or need more information, you'd still create a
QFutureWatcher of course, as it provides more information than a simple
"done".
André
More information about the Development
mailing list