[ggerganov/llama.cpp]即使不处于交互模式,也启用 sigint 处理程序

2024-07-05 392 views
4

处理信号处理的两个问题:

  1. 例如,当用作 docker 容器中的入口点时main,不会捕获 ^C 并且无法终止(没有 kill -9)。
  2. 此外,当前的信号处理代码有些不一致,定义了一个信号处理程序,但除非请求 -i,否则不会将其设置为处理程序。这导致控制台清理未被调用(并且不会输出时间)。

此代码:

  1. 添加 --sigint 以便 CTRL-C 将在非交互模式下立即执行清理+计时+退出。

备择方案:

  1. 启用非交互模式的 sigint 处理程序;也就是说,启用双击 CTRL-C 来中止。(注意:之前的代码似乎可能打算这样做,但除非指定 -i,否则它不会分配 (sigaction()),所以它没有完全到达那里!(因此我指出了 [潜在的] 不一致)。
  2. ...欢迎提出想法...

回答

7

SIGINT 的默认操作是终止进程。这对我来说已经起作用了。llama.cpp 不使用 SIG_IGN,那么为什么 SIGINT 对你不起作用呢?

8

不过,如果 CTRL-C 打印关闭前的时间,就像在交互模式下一样,那就太好了。但我不认为这需要命令行选项,它应该是正常行为。

3

作为入口点,进程变为 pid 1(init)。init 进程不继承信号,只有它自己设置的信号才能发送给它(这是 POSIX 标准)。使用现有代码,除非设置了交互模式,否则我们不会分配信号处理程序。我猜你是:

  1. 不调用 main 作为 docker 入口点(它将成为 init 进程)。(其他代码可能设置了与主示例不同的信号处理程序)。
  2. 您正在使用 -i
  3. ...也许您没有使用符合 posix 标准的系统?:)
7

这就是我设计它的方式。交互模式确实已经给出了时间,但在非交互模式下,我们没有设置信号处理程序,因此您会看到默认信号处理程序启动并终止程序。因此,如果用户指定 --sigint,此更改 (PR) 也会为非交互模式分配我们的信号处理程序(尽管请参阅我的代码中的不一致之处,因为它似乎最初打算这样做,但需要 ^C 才能进入交互模式,然后需要第二个 ^C 才能终止。)

2

您说得对,我保留了之前的默认行为,即不处理 sigint,以防万一需要这种行为。 --sigint 可以启用它。我认为完全删除 --sigint 是可以的,同时仍然添加 SIGINT 的信号处理程序,因为我想不出有多少用例用户真正希望忽略 SIGINT,即使他们将 main 作为 init 运行(即作为入口点)。

(我们也可以设置 --no-sigint)