Chinaunix首页 | 论坛 | 博客
  • 博客访问: 685575
  • 博文数量: 132
  • 博客积分: 10060
  • 博客等级: 上将
  • 技术积分: 1732
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-21 12:35
个人简介

迷惘的码农。

文章分类

全部博文(132)

文章存档

2013年(1)

2011年(2)

2010年(9)

2009年(41)

2008年(79)

我的朋友

分类:

2008-08-15 11:13:47

2.9 -

除了元表,线程、函数和用户数据类型的对象拥有与它们关联的其他表,称为它们环境(environment)。同元表一样,环境是常规表,而且多个对象可以共享同一环境。

对Lua来说,与用户数据关联的环境没有意义。它只是为了方便程序员把表关联到用户数据的方便特性。

同线程关联的环境称为全局环境(global environments)。它们被用作它们的线程和被线程创建的非嵌套函数的缺省环境(通过、或),并且可通过C代码直接访问(见a href="#3.3">§3.3)。

与C函数关联的环境能被C代码直接访问(见)。它们被用作由其创建的其他C函数的缺省环境。

同Lua函数关联的环境被用来解决函数内所有对全局变量的访问(见)。它们被用作由其创建的其他Lua函数的缺省环境。Environments associated with Lua functions are used to resolve all accesses to global variables within the function

可调用来改变Lua函数或当前运行的线程的环境。可调用获取Lua函数或当前运行的线程的环境。要操作其他对象的环境(用户数据、C函数、其他线程),必须使用C API。

2.10 -

Lua提供自动内存管理。这表示你无需担心新对象的内存分配以及当对象不再需要时的释放工作。Lua通过运行有时运行的垃圾收集器(garbage collector)收集所有的死掉的对象(就是说这些对象不能从Lua中访问了)来自动地管理内存。Lua中的所有对象都被自动管理:表、用户数据、函数、线程和字符串。

Lua实现了增量标记清除(mark-and-sweep)收集器。它用两个数字控制垃圾收集周期:garbage-collector pausegarbage-collector step multiplier

garbage-collector pause控制收集器在启动新一轮周期前等待多久。数值越大,收集器的活性越低。小于1意味着收集器在启动新周期前不会等待。值为2意味着收集器等已用内存总量翻倍时启动新周期。

step multiplier控制收集器对内存分配的相对速度。数值越大,收集器的活性越高,同时也增大了每步增量的尺寸。小于1的值使得收集器太慢并且可能导致周期无法完成。缺省值2意味着收集器以内存分配的二倍速运行。

可调用C中的或Lua中的改变这些数值。两者都接受百分点数作为参数(所以参数100表示实际值1)。这些函数也能直接控制(比如停止和重启)收集器。

2.10.1 -

可用C API为用户数据设置垃圾收集器元方法(见)。这些元方法也称为析构器(finalizer)。析构器允许你协调Lua的垃圾收集和外部资源管理(比如关闭文件、网络或数据库连接,或释放你自己的内存)。

元表中带有__gc字段的无用用户数据不会被垃圾收集器立刻回收。代替的做法是,Lua将它们放进一个列表。回收之后,Lua对列表中的每个用户数据执行下面函数的等价操作:

     function gc_event (udata)
local h = metatable(udata).__gc
if h then
h(udata)
end
end

在垃圾收集周期的最后,本周期收集的用户数据的析构器以它们创建的反序被调用。就是说,程序中最后创建的用户数据关联的析构器被第一个调用。用户数据本身只在下一次垃圾收集周期释放。

2.10.2 -

弱引用表(Weak)的元素都是弱引用(weak reference)。弱引用被垃圾收集器忽略(认为是无用的)。换句话说,如果某对象仅有的引用是弱引用,垃圾收集器会回收该对象。

弱引用表可能具有弱引用键、弱引用值或二者都有。具有弱引用键的表允许对其键的回收,但会阻止对其值进行回收。键和值都是弱引用得表允许对二者的回收。无论键或值被回收,整个键值对从表中移除。表的弱引用性由其元表的__mode字段控制。如果该字段是个包含‘k’的字符串,表中的键是弱引用的。如果含有‘v’,值是弱引用的。

把某个表用作元表后就不能修改其__mode字段的值了。否则,该元表控制的表的弱引用行为就是未定义的。

2.11 -

Lua支持协同例程,也称为协同式多线程(collaborative multithreading)。Lua中的协程描绘对立的执行线程。不同于多线程系统中的线程,协程只能通过显式地调用中断(yield)函数暂停自身的执行。

调用创建一个协程。它的唯一参数是协程的主函数。函数create只是创建一个新协程并返回指向它(thread类型的对象)的句柄;它并没启动协程执行。

首次调用并传入由返回的线程作为第一参数时,协程在其主函数的第一行启动运行。传入的额外参数被传入协程的主函数。协程启动运行后会一直运行直到结束或中断.

协程有两种方式结束它的运行:正常的,当它的主函数返回(显式或隐式地,在最后指令之后)时;非正常的,发生未预防的错误。第一种情况下,返回true,以及协程主函数返回的任何值。发生错误的情况下,返回false以及一条错误消息。

协程通过调用中断。当协程中断时,相应的立刻返回,即使中断发生在嵌套的函数调用内部(即不在主函数中,而是主函数直接或间接调用的函数中)。中断的情况下,也返回true,以及传入的任何值。下次恢复同样的协程,它从被中断处继续运行,同时对的调用返回的任何额外值作为参数传入。

同一样,函数也创建一个协程,但是它返回一个恢复协程的函数而不是协程本身。传入该函数的任何参数成为的额外参数。除了第一个(错误代码布尔值),返回的值也都返回。与不同的是,不会捕获错误;任何错误都被传播到调用者。

作为一个例子,考虑下面的代码:

     function foo (a)
print("foo", a)
return coroutine.yield(2*a)
end

co = coroutine.create(function (a,b)
print("co-body", a, b)
local r = foo(a+1)
print("co-body", r)
local r, s = coroutine.yield(a+b, a-b)
print("co-body", r, s)
return b, "end"
end)

print("main", coroutine.resume(co, 1, 10))
print("main", coroutine.resume(co, "r"))
print("main", coroutine.resume(co, "x", "y"))
print("main", coroutine.resume(co, "x", "y"))

运行时它会产生下面的输出:

     co-body 1       10
foo 2

main true 4
co-body r
main true 11 -9
co-body x y
main true 10 end
main false cannot resume dead coroutine
阅读(1546) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~