lua - 让两个 lua 线程在同一个 lua 状态下并行运行而不并发执行是否安全?
问题描述
我们正在使用 lua 开发游戏服务器。
服务器是单线程的,我们将从 C++ 调用 lua。
每个 C++ 服务都会从全局 lua 状态创建一个 lua 线程,该状态由所有服务共享。
lua 线程执行的 lua 脚本将调用 ac api,后者将对远程服务器进行 rpc 调用。
然后lua线程被挂起,因为它的c函数永远不会返回。
当 rpc 响应返回时,我们将继续 c 代码,这将返回到 lua 脚本。
因此,我们将有多个 lua 线程在同一个全局 lua 状态上并行执行,但它们永远不会同时运行。而suspend不是引起的而是lua的yield函数,而是来自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;
}
解决方案
推荐阅读
- javascript - 试图附加到 HTML 的 JavaScript 不起作用
- python - 如何根据 Python pandas DataFrame 中单元格的值为不同的单元格着色
- php - 正则表达式匹配以某些单词和符号开头和结尾的所有行
- css - CSS 仅删除 AMP 帖子的元素
- node.js - 当用户加入服务器时,我如何 DM 用户?
- visual-studio - 如何使用 VSCode 在 docker 中创建自定义图像?
- c++ - 有向图列表算法帮助
- .net - 找不到类型 [Microsoft.Build.Construction.SolutionFile]
- objective-c - Swift5无法使用AVAudioRecorder在mac os上录制音频(错误:[插件] AddInstanceForFactory:没有为id注册工厂
为 Mac OS 制作录音机应用程序。使用 AVAudioRecorder 时遇到一个问题。不要崩溃,但总是显示此错误。
错误:[插件] AddInstanceForFactory:没有为 id <CFUUID 注册工厂 ...
错误:HALC
- mysql - 计算 SQL 中计数相对于类别的百分比