Linux服务器开发,skynet网络层封装以及lua/c接口编程

──────────────────────────────────────────────────────────────
┌————————————┐
│▉▉♥♥♥♥♥♥♥♥ 99% │ ♥❤ 鱼沈雁杳天涯路,始信人间别离苦。
└————————————┘
对你的感情正在充电中,请稍侯…
──────────────────────────────────────────────────────────────

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

──────────────────────────────────────────────────────────────

  • 掌握框架是怎么解决问题的 ➔ 掌握框架的数据流
  • 掌握框架的核心开发技能 ➔ 掌握增加补充组件(本篇重点)
  • 掌握框架的开发思路 ➔ 掌握解决问题的方法
    Linux服务器开发,skynet网络层封装以及lua/c接口编程_第1张图片
    回调函数是actor模型的入口点,它直接将数据传到了lua层。

──────────────────────────────────────────────────────────────

skynet网络层封装以及lua/c接口编程

    • 一、lua(胶水语言)开发,运行速度最快,适合业务逻辑,不能多线程
      • 用户抽象
        • 一个用户对应一个抽象,不一定正确。
      • 底层抽象
        • 1.一个actor一个虚拟机
        • 2.一个c语言接口
        • 3.一个actor一个消息队列
        • 4.一个消息对应一个携程处理
        • 5.一个actor只能跑在一个线程
    • 二、c/lua接口编程
      • lua数据类型
      • lua和c交互时利用一个虚拟栈
      • 重要元表
      • 注意事项
      • 闭包
      • 虚拟栈
      • 编程接口步骤及规范
        • 1.头文件
        • 2.导出模块
        • 3.导出接口
        • 4.写接口
        • 5.Makefile 编译成动态库(待完善)
    • 三、c服务(actor待完善)

一、lua(胶水语言)开发,运行速度最快,适合业务逻辑,不能多线程

用户抽象

一个用户对应一个抽象,不一定正确。

底层抽象

1.一个actor一个虚拟机

2.一个c语言接口

3.一个actor一个消息队列

4.一个消息对应一个携程处理

5.一个actor只能跑在一个线程

  • 一个actor只能被一个线程调度
  • 根据工作线程的权重去调度actor。-1表示:每次只取一个消息处理。0表示:每次取所有消息运行。
    Linux服务器开发,skynet网络层封装以及lua/c接口编程_第2张图片
    actor通过多线程的方式去利用多核cpu。

二、c/lua接口编程

lua数据类型

  • boolen:true和false;其中false可以解决table作为array时,元素为nil时造成table取长度未定义的行为。
  • number:为interger和double的总称。
  • string:常量字符串;这样lua中字符串比较只需要进行地址比较就行了。
  • nil:通常表示未定和不存在的两种语义。
  • function:与其他语言不同的是,lua中function为第一类型;注意lua中的匿名函数,lua文件可视为一个匿名函数;加载lua文件,可视为执行该匿名函数。
  • table: lua中唯一的数据结构;既可以表示hashtable也可以表示array;配合元表就可以定制复杂的功能。
  • userdata:完全用户书数据;指向一块内存的指针,通过为userdata设置元素,lua层可以使用该userdata提供的功能;userdata为lua补充了数据结构,解决了lua数据结构单一的问题;可以在c中实现复杂的数据结构吗,生成库继而导出给lua使用;注意:userdata指向的内存需要由lua创建,同时userdata的销毁也交由lua gc来自动回收。
  • lightusrerdata:轻量用户书库;也是指向一块内存的指针,但是该内存由c创建,同时它的销毁也有c来完成;不能为他创建元素,轻量用户数据只有类型元素,通常用于lua想使用c的结构,但是不能让lua来释放的结构;在客户端中使用较多。
  • thread线程:lua中的携程和虚拟机都是thread类型。
//数组从一开始,并非从零开始
+ local tab={[1]=1,[2]=2,[3]=3,[4]=4}
+ local tab={1,2,3,4,["mark"]=5}
//lua 深入的探讨要等以后啦!可以参看lua5.3的参考手册

lua和c交互时利用一个虚拟栈

Linux服务器开发,skynet网络层封装以及lua/c接口编程_第3张图片

重要元表

local tab={[1]=]1,[2]=2,[3]=3,}
local newtab=setmetable{tab,{__index =	 function(t,k)
									 return "不存在"
									 end,
							 __newindex= function(t,v,k)
							 		print("__newindex",v,k)
							 		error ("不能修改t")
							 		end,
							 __gc =		function(t)
							 		print("gc")
							 		end
							})
tab[4]=10  
print(tab[4])
  • __index:索引table[table]。当table不是表或是表table中不存在key这个键时,这个时间被触发。此时,会对出table相应得元方法。
  • __newindex:索引赋值table[key]=value。和索引事件类似,它发生在table不是表或时表table中不存在key这个键的时候。此时,会读出table相应的方法。
  • __gc:元表中用一个以字符串“__gc”为索引的域,那么就标记了这个对象需要的触发终结器。除去lightusrerdata这个数据类型,其他的数据类型都需要使用__gc。

注意事项

  • 只有table和userdata对象有独自的元表,其他类型只有类型元素。
  • 只有table可以在lua中修改设置元表。
  • userdata 只能在c中修改设置元表,lua中不能修改userdata元表。
local co=coroutine.create(function(arg1))
		local ret1 =arf1 + 1
		local arg2=coroutine.yield(ret1)
		local ret2=arg2+1
		return ret2
end)
local co1=coroutine.runing()
local arg1=1
local ok,ret1,ret2
ok,ret1=coroutine.resume(co,arg1)
print(co1,ok,ret1)
ok,ret2=coroutine.resume(co,ret1)
print(co1,ok,ret2)

闭包

local args
local function func()
		args = "hello"
end
local funtion func()
		local args ="hello"
		return funtion()
			   args =args.. "world"
			   return args
		end
end
local ff=func()
print(ff()) //hello
print(ff()) //hello world
print(ff()) //hello world world

需要注意的是,在c语言中0表示false,而在lua脚本中0是一个数值,它表示true。
not nil 和not false相当于c语言的true,~=表示不等于。

Linux服务器开发,skynet网络层封装以及lua/c接口编程_第4张图片

虚拟栈

  • 栈中只能存放lua类型的值,如果i想用的c的类型存储的栈中,需要将c类型转换为lua类型;
  • c调用lua,每一个下协程都有一个栈;lua调用c的函数都得到一个新的栈,独立于之前的栈;
  • c调用lua,每一个协程都有一个栈;
  • c创建虚拟机时,伴随创建了一个主协程,默认创建一个虚拟栈;
  • 无论何时Lua调用c,它都只保证至少有LUA_MINSTACK这么多的堆栈空间可以使用。LUA_MINSTACK一般被定义为20.因此,只要你不是不断的把数据压栈,通常你不用关心堆栈的大小。
  • lua调c会自动释放栈,而c调用lua不会自动释放栈。

编程接口步骤及规范

1.头文件

#include 
#include 
#include 
#include 

2.导出模块

每一个模块都需要找出一个这样的接口。

int luaopen_uv_c(lua_state *L)

对应的lua方面

require "uv.c"

3.导出接口

static const luaL_Reg l[]={
		{"echo",lecho},
		{NULL,NULL},
};
int luaopen_uv_c(lua_State * L){
	luaL_newlibtable(L,l);  //1
	lua_pushinteger(L,0);   //2
	lua_setfuncs(L,l,1);    //上值
	//luaL_newlib(L,1);
	return 1;
}
local so=require "uv.c"
so.echo   
//echo为lua使用,lecho为c语言实现接口

4.写接口

//只需要一个参数,lua_***表示操作lua虚拟栈。

static int
lecho (lua_State *L){
		lua_Integer n=lua_tointeger(L,lua_upvalueindex(1));
		n++;
		const char * str =lua_tostring(L,-1);
		fprintf(stdout,"[n=%lld]---%s \n",n,str);
		lua_pushinteger(L,n);
		lua_replace(L,lua_upvalueindex(1));
		return 0;
}
  • lua是不能直接调用c语言的,需要将c语言封装成库。
  • 闭包是语言的一个特性,相当于类额私有成员。

5.Makefile 编译成动态库(待完善)

Linux服务器开发,skynet网络层封装以及lua/c接口编程_第5张图片
Linux服务器开发,skynet网络层封装以及lua/c接口编程_第6张图片

三、c服务(actor待完善)

Linux服务器开发,skynet网络层封装以及lua/c接口编程_第7张图片
Linux服务器开发,skynet网络层封装以及lua/c接口编程_第8张图片

你可能感兴趣的:(lua,服务器,linux)