Я перенес наше приложение из Objective-C и Cocoa в C ++.В Objective-C я часто использовал Grand Central Dispatch и очень удобные функции dispatch_async.
При переходе на C ++ 11 я нашел std :: async в качестве ближайшего аналога.Я использую его вариант Скотта Мейерса, который гарантирует, что он действительно вызывается асинхронно:
template<typename F, typename... Ts>
inline auto NLA_async(F&& f, Ts&&... params)
{
return std::async(std::launch::async,
std::forward<F>(f),
std::forward<Ts>(params)...);
}
Я узнал, что функция на самом деле не будет вызываться асинхронно, если возвращенное будущее не назначено как будущее d 'tor будет ожидать завершения асинхронного блока.
void foo()
{
NLA_async([]{ // run long task async });
// future returned from NLA_async not captured
// -> std::future d'tor waits for block to be finished
}
Поэтому я подумал, что просто назначу будущее члену класса, чтобы он по крайней мере отправлял асинхронно в большинстве случаев (не идеально, но ядумал быстрый и грязный обходной путь).До сих пор это работало хорошо.
Однако я нахожусь в тупиковой ситуации, которую я пока не понимаю.Похоже, что возможно, что блок выполняется дважды одновременно, что в моем случае вызывает тупик.
Вы можете посмотреть здесь:
http://coliru.stacked - криво.com / a / dc4fcbaff370f1b9
Кто-нибудь может объяснить, почему это выполняется дважды одновременно?
Редактировать: В моем конкретном случае проблема заключается в том, что в конце асинхронногозаблокировать код блокирует мьютекс, выполняет некоторую работу, а затем разблокирует мьютекс.На данный момент мы заходим в тупик.Похоже, что работающий асинхронный блок удаляется до его завершения, так как мьютекс остается заблокированным, хотя и не должен (нет операторов возврата или чего-либо, что могло бы объяснить, почему он не разблокирует мьютекс).