Доступны ли блоки и libdispatch в Linux? - PullRequest
13 голосов
/ 12 апреля 2011

Я бы с удовольствием попробовал грандиозную центральную диспетчеризацию, но все, что мне нужно для разработки, это рабочая станция Ubuntu.Доступен ли в Linux пакет libdispatch и расширение блоков для c / obj-c и т. Д.?Если да, то как их получить?

Ответы [ 4 ]

13 голосов
/ 12 апреля 2011

Вам может понадобиться использовать компилятор LLVM (доступный в Ubuntu) для получения блоков в настоящее время (я не думаю, что это доступно в gcc, но я не следил за с gcc, так что я могу ошибаться.)

В настоящее время предпринимаются усилия по переносу libdispatch (домой для libdispatch с открытым исходным кодом) для Linux. Кажется, что большая часть усилий на Debian, но некоторые на других дистрибутивах. Смотрите эти темы для обсуждения:

6 голосов
/ 11 декабря 2012

Я проделал некоторую работу, чтобы заставить версию OS X Mountain Lion libdispatch работать на Linux;результат на Github: http://nickhutchinson.me/libdispatch/.

1 голос
/ 24 апреля 2016

Используйте clang-3.4.

  • sudo apt-get install libdispatch-dev
  • sudo apt-get install libblocks-runtime-dev
  • Компилировать с -fblocks
  • Ссылка с -lBlocksRuntime -ldispatch
0 голосов
/ 22 апреля 2014

Вместо того, чтобы использовать блоки, используйте лямбды 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(); });
...