Gauche > Archives > 2017/01/06

2017/01/06 17:34:48 UTCとおる。
#
C API で Gauche の文字列を作ろうと思って、Scm_MakeString を使ってみたんですが、これってメモリの解放はどうやるのが正しいでしょうか?
2017/01/06 17:56:59 UTCとおる。
#
かなり適当ですが、Libuv のメインループから Gauche を呼び出す実験をしてみました。 https://github.com/torus/gauche-violet
2017/01/06 19:35:42 UTCshiro
#
>とおる。 引数に渡すchar*もGauche経由でアロケートしてた場合はGaucheのGCが面倒を見るので気にしないで可。そうでない場合はflagsにSCM_STRING_COPYINGを渡すとGauche側でGCマネージドメモリにコピーするので、caller側で必要なら解法してください。
2017/01/06 19:38:30 UTCとおる。
#
あーなるほど。ありがとうございます!
2017/01/06 19:39:37 UTCshiro
#
CからSchemeの手続きを呼ぶ時のルックアップにはSCM_BIND_PROCという便利マクロがあります https://github.com/shirok/Gauche/blob/master/src/gauche.h#L1538
2017/01/06 19:44:34 UTCとおる。
#
おお! これは便利!
2017/01/06 20:17:03 UTCとおる。
#
Gauche の http-get とかの HTTP 通信を非同期に実行する方法ってないでしょうか?
2017/01/06 20:38:12 UTCshiro
#
今ある機能でやるならスレッドですねぇ…
2017/01/06 20:41:26 UTCとおる。
#
ああ、やっぱり、そうなりますよねぇ。
2017/01/06 21:17:12 UTCshiro
#
libuv等使ったイベント駆動のモデルとすり合わせるには、スレッドプールでリクエストを実行するのをfutureみたいなオブジェクトにラップするという手はありますが、実行が完了したことをイベントループ側に伝えないとならないですね。
2017/01/06 21:36:41 UTCとおる。
#
実行が完了した事を伝えるのはキューとかを使えばいいかなぁと思うんですが、Libuv はシングルスレッドを保つことでパフォーマンスをだしているので、マルチスレッドにするとちょっともったいないと思うんですよねぇ。
#
実際どの程度パフォーマンスのロスがあるのか分かりませんけど。
2017/01/06 21:51:31 UTCshiro
#
パラダイムが違うからなあ。Gaucheでもユーザ空間の軽量スレッドを持ち込む計画はかすかにあるんだけれど、Schemeから見たらスレッドとして同じように見えるようにすると思う。でもその場合、内部スケジューラとlibuvとの協調がむしろ難しくなるかもな…
#
でも、libuvの性能を全開にするために他のスレッドを走らせたくない、という場合、GaucheはデフォルトでGCがマルチスレッドで走るのでそこも変える必要がありそうな。しかしイベントループスレッドでGCが走るのも気持ち悪くはあるな。
#
別スレッドへのコンテキストスイッチを許容したとしても、「大部分のイベント処理はシングルスレッドで走るのでリソースを食いにくい」ってメリットは享受できると思う。
2017/01/06 22:02:59 UTCとおる。
#
なるほど。まあ GC のようにたまにしか走らないようなものはいいかなと思うんですが、例えばウェブアプリケーションを走らせる場合は、DB コネクションや外部のウェブ API へのアクセスなどのネットワーク IO はおそらく同時接続数と同程度のオーダーで増えると思うので、そうなるとコンテキストスイッチのオーバーヘッドもバカにならないかなぁと思ってます。
#
ただ、シングルスレッドの利点としてはリソースのアクセスの競合を気にしなくて良いというのがあるので、その辺は裏の処理が別のスレッドで動いていても問題ないですね。
2017/01/06 22:10:40 UTCshiro
#
数百以上のリクエストをカーネルスレッドで待つようになるときついのはきついですね。非同期I/Oライブラリを別に作ろうと思えばある程度できるんだろうけれど、CでやってたようなことをSchemeでやり直すのも変だしなあ。Schemeから見たらやっぱりスレッドで、システムコール投げるAPIがユーザレベルスレッドをスイッチするってのがやっぱり落としどころかなあと思ってます。Biglooだかがそんな感じだったような。
2017/01/06 22:16:42 UTCとおる。
#
Scheme だと、内部の API は非同期でも、継続を使えばアプリケーションのコードは同期みたいに見えるので、Node.js とかに比べたら扱いやすいと思うんですよね。
#
Node.js もジェネレータが使えるようになったけど、Scheme の継続ほど便利じゃないんですよねぇ。
2017/01/06 22:30:58 UTCshiro
#
原理的には、ブロックするシステムコールのところで継続をテーブルに登録して、アベラブルになったシステムコールに関連付けられた継続を再起動して、とやればいいんですが、Gaucheの場合Cスタックの深いところでシステムコールを呼び出すケースがあるので手軽に継続が取れないのが難点。API的にasync/awaitみたいのはスレッドプールと組み合わせれば簡単にできると思うけど。
2017/01/06 23:24:23 UTCとおる。
#
むー、なるほど。。。