[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Is is possible to use just one lua virtual machine in C coroutine framework?
- From: =?gb18030?b?xe0gyum09A==?= <nerditation@...>
- Date: Sat, 28 Jul 2018 14:01:53 +0000
在 2018/7/25 10:03, 小爬虫 写道:
> I've worked on a C coroutine framework implemented with ucontext.
> For each client request, the framework will alloc a C coroutine to process the request.
> I wanna add lua to this system. However, I met some problems.
> It's hard to change C coroutine to lua coroutine, since it's a big codebase. Use lua as glue to aggregate all the C api seems a reasonable way.
> So lua will not use coroutine, leave the coroutine to C.
> However, the C stack changes when switch C coroutines. It's possible to use multiple lua virtual machine, one for each C coroutine. But it is not efficient. Each creation of C Coroutine will need create a new virtual machine and load all the scripts.
> If I use only one Lua virtual machine,and create thread for each coroutine, it's much more light-weighted and scripts can be shared among different lua_thread. However, the switch execution of C coroutine requires lua_thread to be suspended and resumed. Since lua only allow one running lua_thread.
> Are these any solutions for this problem? Thanks in advance.
I don't know much about ucontext, but if you are stuck with your current C coroutine system,
I don't think there is a better solution in plain Lua, other than one Lua VM for each C coroutine.
actually this might not be as bad as you would think. you should always measure.
if you are not restricted to your own C coroutine system, and you are OK with a patched Lua VM,
there is a patch from LuaJIT 1.x branch called coco, which essentially rebuilt Lua's
coroutine on top of a custom C coroutine system, implemented using platform specific tricks.
it is very cool, and actually compatible with plain Lua (not ABI compatible for C modules of course).
although the patch is for Lua 5.1, it should not be very hard to adapt it to current version,
once you understands the implementation mechanism.
basically, lua_newthread(), will allocate a new C stack (with a stub context pointing to
a thunk of code) and associate the stack with the lua_State. lua_resume() switches to the new stack
and then jump into the context. lua_yield() saves current context then jump out to previous context.
so instead of integrate Lua's coroutine with your C coroutine system, you can implement your coroutine
system on top of Lua/coco's coroutine.
for example, coroutine_create() can be implemented as lua_newthread() followed by lua_pushcfunction()
coroutine_resume() is just lua_resume(), and coroutine_suspend() is just lua_yield().
you can directly use L as your coroutine handle.
you may need to differentiate Lua yields and C library yields in your scheduler/IO-multiplexer though,
but that should be straightforward.
the nerdy Peng / 书呆彭 /