我遇到的所有协程实现都使用汇编或检查内容jmp_buf.这个问题是它本身不是跨平台的.
我认为以下实现不会进入未定义的行为或依赖于实现细节.但我从来没有遇到像这样写的协程.
是否有一些固有的缺陷是使用线程跳远?
这段代码中有一些隐藏的问题吗?
#include <setjmp.h>
#include <thread>
class Coroutine
{
public:
Coroutine( void ) :
m_done( false ),
m_thread( [&](){ this->start(); } )
{ }
~Coroutine( void )
{
std::lock_guard<std::mutex> lock( m_mutex );
m_done = true;
m_condition.notify_one();
m_thread.join();
}
void start( void )
{
if( setjmp( m_resume ) == 0 )
{
std::unique_lock<std::mutex> lock( m_mutex );
m_condition.wait( lock, [&](){ return m_done; } );
}
else
{
routine();
longjmp( m_yield, 1 );
}
}
void resume( void ) …Run Code Online (Sandbox Code Playgroud) 我试图了解如何使用协同例程来"暂停"一个脚本并等待一些处理完成后再恢复.
也许我正在以错误的方式看待惯例.但我的尝试结构类似于这个答案中给出的例子.
循环loop.lua永远不会达到第二次迭代,因此永远不会达到i == 4退出C代码中的运行循环所需的条件.如果我不屈服loop.lua,则此代码按预期执行.
main.cpp中
#include <lua/lua.hpp>
bool running = true;
int lua_finish(lua_State *) {
running = false;
printf("lua_finish called\n");
return 0;
}
int lua_sleep(lua_State *L) {
printf("lua_sleep called\n");
return lua_yield(L,0);
}
int main() {
lua_State* L = lua_open();
luaL_openlibs(L);
lua_register(L, "sleep", lua_sleep);
lua_register(L, "finish", lua_finish);
luaL_dofile(L, "scripts/init.lua");
lua_State* cL = lua_newthread(L);
luaL_dofile(cL, "scripts/loop.lua");
while (running) {
int status;
status = lua_resume(cL,0);
if (status == LUA_YIELD) {
printf("loop yielding\n");
} else …Run Code Online (Sandbox Code Playgroud) 我有一个回调系统,它可以将lua函数添加到C++处理程序,例如我可以做的lua
myCObject:AddCallback(luaFunc)
Run Code Online (Sandbox Code Playgroud)
对于协程,我也有相同的
myCObject:AddCallback(coroutine.create(luaFunc))
Run Code Online (Sandbox Code Playgroud)
然后我可以使用
lua_State * pThread = lua_tothread(L, -1);
lua_resume(pThread, 0,0);
Run Code Online (Sandbox Code Playgroud)
在C++中
启动/恢复lua功能.
现在,我不想要脚本编写者写coroutine.create(luaFunc) - 我只是想自动"转换"一个lua func到一个协程.当调用AddCallback时,我在堆栈上有luaFunc - 然后我该如何继续?(使用coroutine.create我已经在堆栈上有一个线程)
编辑:我正在寻找使用C API的解决方案,例如lua_newthread