在没有并发执行的情况下,让两个lua线程在同一lua状态下并行运行是否安全?

时间:2018-08-01 07:18:23

标签: lua coroutine ucontext

我们正在使用lua开发游戏服务器。

服务器是单线程的,我们将从c ++调用lua。

每个c ++服务都会从全局lua状态创建一个lua线程,该状态会被所有服务共享。

由lua线程执行的lua脚本将调用一个c api,它将对远程服务器进行rpc调用。

然后挂起lua线程,因为它的c函数永远不会返回。

当rpc响应返回时,我们将继续执行c代码,这将返回lua脚本。

因此,我们将有多个lua线程在相同的全局lua状态下并行执行,但它们永远不会同时运行。并且挂起不是由lua产生函数引起的,而是从c端引起的。

这样做是安全的吗?

#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#include "lua/lua.hpp"

static ucontext_t uctx_main, uctx_func1, uctx_func2;

lua_State* gLvm;
int gCallCnt = 0;

static int proc(lua_State *L) {
    int iID = atoi(lua_tostring(L, -1));

    printf("begin proc, %s\n", lua_tostring(L, -1));
    if(iID == 1)
    {
        swapcontext(&uctx_func1, &uctx_main);
    }
    else
    {
        swapcontext(&uctx_func2, &uctx_main);
    }
    printf("end proc, %s\n", lua_tostring(L, -1));
    return 0;  
}

static void func1(void)
{
    gCallCnt++;
    printf("hello, func1\n");

    lua_State*thread = lua_newthread (gLvm);

    lua_getglobal(thread, "proc");
    char szTmp[20];
    sprintf(szTmp, "%d", gCallCnt);
    lua_pushstring(thread, szTmp);
    int iRet = lua_resume(thread, gLvm, 1);
    printf("lua_resume return:%d\n", iRet);
}

static void func2(void)
{
    gCallCnt++;
    printf("hello, func2\n");

    lua_State*thread = lua_newthread (gLvm);

    lua_getglobal(thread, "proc");
    char szTmp[20];
    sprintf(szTmp, "%d", gCallCnt);
    lua_pushstring(thread, szTmp);
    int iRet = lua_resume(thread, gLvm, 1);
    printf("lua_resume return:%d\n", iRet);
}



int main(int argc, char *argv[]){
    int iRet = 0;

    gLvm = luaL_newstate();
    luaL_openlibs(gLvm);

    lua_pushcfunction(gLvm, proc);
    lua_setglobal(gLvm, "proc");

    char func1_stack[16384];
    char func2_stack[16384];
    getcontext(&uctx_func1);
    uctx_func1.uc_stack.ss_sp = func1_stack;
    uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
    uctx_func1.uc_link = &uctx_main;
    makecontext(&uctx_func1, func1, 0);

    getcontext(&uctx_func2);
    uctx_func2.uc_stack.ss_sp = func2_stack;
    uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
    uctx_func2.uc_link = &uctx_main;
    makecontext(&uctx_func2, func2, 0);

    swapcontext(&uctx_main, &uctx_func1);

    swapcontext(&uctx_main, &uctx_func2);

    swapcontext(&uctx_main, &uctx_func1);

    swapcontext(&uctx_main, &uctx_func2);

    printf("hello, main\n");

    return 0;
}

0 个答案:

没有答案