Доступны ли блоки и libdispatch в Linux?
Я бы с удовольствием попробовал грандиозную центральную диспетчеризацию, но все, что мне нужно для разработки, это рабочая станция Ubuntu. Доступен ли в Linux пакет libdispatch и расширение блоков для c/obj-c и т. Д.? Если так, как я могу получить их?
4 ответа
Вам может понадобиться использовать компилятор LLVM Clang (доступный в Ubuntu) для получения блоков в это время (я не думаю, что это доступно в gcc, но я не следил за gcc, так что я могу ошибаться.)
В настоящее время предпринимаются усилия по переносу libdispatch (дома с открытым исходным кодом libdispatch) на Linux. Кажется, что большая часть усилий на Debian, но некоторые на других дистрибутивах. Смотрите эти темы для обсуждения:
- linux + libdispatch + clang + блоки
- Обновление статуса портирования libdispatch
- Отправка Grand Central для Debian (заархивированная ссылка)
Я проделал некоторую работу, чтобы заставить версию OS X Mountain Lion libdispatch работать на Linux; Результат на Github: http://nickhutchinson.me/libdispatch/.
Используйте clang-3.4.
- sudo apt-get установить libdispatch-dev
- sudo apt-get установить libblocks-runtime-dev
- Компилировать с -fblocks
- Ссылка с -lBlocksRuntime -ldispatch
Вместо того, чтобы использовать блоки, используйте лямбды C++. Они играют лучше с с ++ и в них меньше скрытой магии.
Я делаю это так:
/// Dispatch a function object to a queue.
template<class F>
static void dispatch_async_function(dispatch_queue_t queue, F f) {
struct context_t {
using function_type = F;
context_t(function_type&& f) noexcept
: _f(std::move(f))
{}
static void execute(void* p) noexcept {
auto context = reinterpret_cast<context_t*>(p);
if (context) {
try {
context->_f();
}
catch(...) {
// error processing here
}
delete context;
}
}
private:
function_type _f;
};
dispatch_async_f(queue, new context_t<F>(std::move(f)), &context_t<F>::execute);
}
И если вам нужно убедиться, что какой-то общий ресурс существует до вызова (например, обратный вызов для объекта, который поддерживается живым с помощью общего указателя):
/// Dispatch a function object to a queue. Only execute the function if the tie
/// locks successfully.
template<class F>
static void dispatch_async_tied_function(dispatch_queue_t queue, std::weak_ptr<void> tie, F f) {
struct context_t {
using function_type = F;
context_t(function_type&& f) noexcept
: _f(std::move(f))
{}
static void execute(void* p) noexcept {
auto context = reinterpret_cast<context_t*>(p);
auto lock = _tie.lock();
if (context && tie) {
try {
context->_f();
}
catch(...) {
// error processing here
}
delete context;
}
}
private:
function_type _f;
std::weak_ptr<void> _tie;
};
dispatch_async_f(queue, new context_t<F>(std::move(f)), &context_t<F>::execute);
}
называть их так
dispatch_function(queue, []() { something(); });
или же...
dispatch_tied_function(_myQueue, shared_from_this(), [this]() { somethingOnThis(); });