グランド セントラル ディスパッチを試してみたいのですが、開発する必要があるのは Ubuntu ワークステーションだけです。libdispatch や c/obj-c などへのブロック拡張は Linux で利用できますか? もしそうなら、どうすれば入手できますか?
4 に答える
現時点では、LLVM Clang (Ubuntu で利用可能)コンパイラを使用してブロックを取得する必要があるかもしれません (これはまだ gcc では利用できないと思いますが、gcc についていけていないので、間違っている可能性があります。 )
libdispatch (オープン ソース libdispatch のホーム)を Linuxに移植する取り組みが進行中です。これまでのところ、ほとんどの作業は Debian で行われているようですが、一部は他のディストリビューションでも行われています。次のディスカッション スレッドを参照してください。
libdispatch の OS X Mountain Lion バージョンを Linux で動作させるために、いくつかの作業を行いました。結果は Github にあります: http://nickhutchinson.me/libdispatch/。
clang-3.4 を使用します。
- sudo apt-get インストール libdispatch-dev
- sudo apt-get install libblocks-runtime-dev
- -fblocks でコンパイル
- -lBlocksRuntime -ldispatch とのリンク
ブロックを使用するのではなく、c++ ラムダを使用します。それらは 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(); });