问题
When I have been trying to implement "parallel for" using QtConcurrent::map:
QFuture<void> parForAsync(size_t n, std::function<void (size_t)> Op)
{
size_t nThreads =
static_cast<size_t>(QThreadPool::globalInstance()->maxThreadCount());
size_t nn = n/nThreads + 1;
using Sequence = QVector<std::function<void()>>;
Sequence vFuns;
for(size_t i = 0; i < n; i+=nn)
{
size_t firstIdx = i,
lastIdx = i + nn > n ? n : i + nn;
vFuns.push_back([=]()->void
{
for(size_t i = firstIdx; i < lastIdx; ++i)
{
Op(i);
}
});
}
return QtConcurrent::map<Sequence> //<-Segmentation fault!
(vFuns, [](std::function<void()> f)
{
f();
});
}
I've got segmentation fault in this place:
template<typename _Res, typename... _ArgTypes>
function<_Res(_ArgTypes...)>::
function(const function& __x)
: _Function_base()
{
if (static_cast<bool>(__x))
{
__x._M_manager(_M_functor, __x._M_functor, __clone_functor); //<-Segmentation fault!
_M_invoker = __x._M_invoker;
_M_manager = __x._M_manager;
}
}
Why is this happening? It seems that std::function had passed checking. How can I make this code working?
Thanks in advance!
回答1:
I cannot reproduce your case but I can give you some example to illustrate issue
QFuture<void> test ()
{
QVector<int> v; // LOCAL VARIABLE IN SCOPE OF test FUNCTION
// preparing v vector
QFuture<void> f = QtConcurrent::map(v,someFunction); // returns immediately
return f;
}
[1] QtConcurrent::map
takes v
by reference NOT BY COPY.
[2] QtConcurrent::map
returns immediately.
[3] So when test
function ends, parallel operations started by map
use v
vector which was deleted because it is local variable in test
function.
You can use waitForFinished
for QFuture
but then your function doesn't make sense because it blocks until parallel task ends.
来源:https://stackoverflow.com/questions/52431737/qtconcurrentmap-segmentation-fault