如何使Lua中的print或write函数具有原子性?

我使用以下代码来同时使用多个核心向文件或标准输出写入:

f:write(x, "\t", y, "\n")
print(x, '\t', y, '\n')

如何使这些语句原子而不会竞争?

更新:似乎我的问题引起了混淆。因此,我会提出更具体的问题:如果我在不同的处理器上运行上述代码,但将输出导入相同的文件,如何确保来自不同处理器的输出符合预期地保留在不同行中?

点赞
用户1009479
用户1009479

Lua本身不支持真正的多线程。因此,在多核处理器中,不会出现类似竞争的问题。请注意,这意味着在您的代码中,f:writeprint不会同时执行。

2014-06-18 12:34:06
用户3677376
用户3677376

如果使用 ..连接子串,那么将结果字符串一次性传递给OS的机率就会增加。

f:write( x .. "\t" .. y .. "\n" )
f:flush()
io.write( tostring( x ) .. "\t" .. tostring( y ) .. "\n" )
io.flush()

这对于像日志记录这样不太重要的任务来说可能已经足够了。如果不够好,您需要对输出操作进行序列化。一个可能的方法是文件锁定。流行的 luafilesystem 模块(可在所有主要桌面操作系统上使用)包括用于此目的的 lockunlock 函数:

local lfs = require( "lfs" )

while not lfs.lock( f, "w" ) do end
f:write( x, "\t", y, "\n" )
f:flush()
lfs.unlock( f )
f:close()

不幸的是,您必须对锁执行繁忙等待。如果您能够在 luaposix 中使用 fcntl 函数(仅适用于类UNIX操作系统,如Linux或MacOS),则可以使调用进程阻塞,直到可以获取锁(参见此处 有一个示例,但使用 F_SETLKW 替换 F_SETLK)。 (对于 print 情况,我会在某个地方使用一个临时文件上的锁定-我还没有找到一个提供访问信号量或等效物的 Lua 模块。)

2014-08-30 03:38:11