如何在Linux下的luajit中捕获SIGUSR1?

我想在luajit中捕获SIGINT.最终我希望能够捕获SIGUSR1.目的是允许我编写logrotate compatable日志记录,在收到SIGUSR1时,日志文件被关闭然后重新打开.

我怎么能用FFI做到这一点?

这是我到目前为止所拥有的.

local ffi = require("ffi")
local C = ffi.C

local SIG_ERR = -1
local SIGINT  = 1
local SIGUSR1 = 10


ffi.cdef[[
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
]]


local function handler(signo)
   print("caught sig\n")
end

if C.signal(SIGINT, handler) == SIG_ERR then
  print("Can't catch SIGINT\n")
end

while 1 do
end

实际上,我认为这里有几件事情.我注意到你必须按两次ctrl c并退出程序.并且“抓住了sig”并没有被称为时间.我认为lua解释器的C端已经捕获了SIGINT.

所以我决定将SIGINT更改为SIGUSR1,因为这最终是我需要的.我注意到它触发了捕获,但我得到了

"PANIC: unprotected error in call to Lua API (bad callback)"

听起来我的回调函数的格式有问题,但我不知道如何纠正它. Lua对我来说仍然是一个新鲜事物.

解决方法:

如果VM已经在主动运行代码,则从信号处理程序调用LuaJIT VM是不安全的. Lua代码是否被解释或编译并不重要.信号处理程序是异步调用的,VM可能不是一致的状态.

您可以创建第二个VM(ffi.C.luaL_newstate()),为该VM中的函数设置信号处理程序,然后以某种方式在两个VM之间进行通信.但这很复杂,很难做到.

我想使用sigpending()(定期检查,例如在日志函数中)或signalfd()(如果你已经有一个事件处理循环)会更容易.

上一篇:调用ctypes函数时,Python int溢出


下一篇:[转]Lua和Lua JIT及优化指南