GNU Pth で良くね?
Lua とか Io とか組み込みたい、って考えたのは要するに二点。 C++ はコンパイル遅いよう、 Fiber が欲しいよう。
前者は D 使えば解決。んじゃ Fiber があればそれで終わり。んじゃ setjmp, longjmp で…っていう yuu さんのネタをひっこぬいて libfiber …って既にありそうだな…と思ってぐぐったら、
http://evanjones.ca/software/threading.html
案の定あった。この文章は良い文章だと思います。 Linux の clone システムコール、 Unix の ucontext.h 、 C89 の setjmp,longjmp のそれぞれで Fiber を実装する方法が紹介されてます。でも libfiber 自体は Unix に依存しているようだな…とか思って、
やっと思い出したのが GNU Pth 。ナゼこれを最初に思いつかなかった。
http://www.gnu.org/software/pth/
D で使ってみた。
extern (C) { alias void* pth_t; static const int PTH_ATTR_DEFAULT = 0; int pth_init(); int pth_kill(); int pth_yield(pth_t p); pth_t pth_spawn(int attr, void* (*)(void*), void*); } extern(C) void* spawn1(void* arg) { printf("1\n"); pth_yield(null); printf("4\n"); return null; } extern(C) void* spawn2(void* arg) { printf("2\n"); pth_yield(null); printf("5\n"); return null; } int main() { pth_t id1, id2; /* please check return value */ pth_init(); id1 = pth_spawn(PTH_ATTR_DEFAULT, &spawn1, null); id2 = pth_spawn(PTH_ATTR_DEFAULT, &spawn2, null); pth_yield(null); printf("3\n"); pth_yield(null); return pth_kill(); }
何の問題もない。 GC というものについて相変わらずサッパリわかっとらんのですけど、大丈夫なんだろうか。まあとりあえず使ってみます。
追記: 今作ってるものに組み込んでみたけどやはし問題無いです。すばらしいです。一体いままで何を悩んでいたんだか。
extern (C) { alias void* pth_t; static const int PTH_ATTR_DEFAULT = 0; int pth_init(); int pth_kill(); int pth_cancel(pth_t); int pth_abort(pth_t); int pth_yield(pth_t p); pth_t pth_spawn(int attr, void* (*)(void*), void*); }
この程度があれば何でもできるみたいです。