Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 立即停止perl守护进程_Linux_Multithreading_Perl_Daemon - Fatal编程技术网

Linux 立即停止perl守护进程

Linux 立即停止perl守护进程,linux,multithreading,perl,daemon,Linux,Multithreading,Perl,Daemon,我有一个运行在用Perl编写的Ubuntu上的守护进程,它现在是单线程的。当它启动时,它执行通常的Proc::Daemon操作,然后进入一个以布尔值为边界的while循环。该守护程序在服务守护程序启动时启动良好。但当我想用服务守护进程stop杀死它时,它不会停止 应该通过使用信号处理程序翻转布尔值来停止: $SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&signalHandler; sub signalHandler { $continue = 0

我有一个运行在用Perl编写的Ubuntu上的守护进程,它现在是单线程的。当它启动时,它执行通常的Proc::Daemon操作,然后进入一个以布尔值为边界的while循环。该守护程序在服务守护程序启动时启动良好。但当我想用服务守护进程stop杀死它时,它不会停止

应该通过使用信号处理程序翻转布尔值来停止:

$SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&signalHandler;

sub signalHandler {
    $continue = 0;
}
不幸的是,主循环中也有睡眠。因此,直到睡眠结束,守护进程才会结束。我希望守护进程立即结束。但我不想设定一个很低的睡眠时间。事实上,我希望能够设置几个小时的睡眠时间,如果这是它决定它应该做的

最好的方法是什么

我在考虑在主循环中调用某种阻塞函数,而不是休眠。这个阻塞函数在某些线程死亡之前不会返回。然后在信号处理程序中,我将简单地杀死休眠线程。这是一个好方法吗?我该怎么做呢,我以前从未用Perl做过多线程


感谢您的帮助

如果您还没有这样做,您可以将任何与关机相关的清理移到自己的子例程中,并让signalHandler调用该清理子例程,然后直接退出。 然后编辑启动/停止脚本,改为发送SIGALRM。信号会干扰睡眠。如果您的脚本被编辑以捕获此信息,则所有内容都将立即停止


进一步阅读:

您可以将任何与关机相关的清理移到它自己的子例程中(如果您还没有这样做),并让signalHandler调用该清理子例程,然后简单地退出。 然后编辑启动/停止脚本,改为发送SIGALRM。信号会干扰睡眠。如果您的脚本被编辑以捕获此信息,则所有内容都将立即停止


进一步阅读:

这里有一个解决这种情况的方法:

一,。在软件开始运行时创建命名管道,例如使用mkfifo

二,。将睡眠调用替换为系统调用,您可以使用perl包而不是select系统调用

设置“选择”以在管道准备好输入时进行监视

select允许指定超时,就像睡眠一样

超过超时时间或满足文件条件时,select调用返回

三,。如果发生超时,请运行循环的主体代码。如果数据显示在管道上,则终止


四,。若要终止,请将数据发送到命名管道

这里有一个解决这种情况的方法:

一,。在软件开始运行时创建命名管道,例如使用mkfifo

二,。将睡眠调用替换为系统调用,您可以使用perl包而不是select系统调用

设置“选择”以在管道准备好输入时进行监视

select允许指定超时,就像睡眠一样

超过超时时间或满足文件条件时,select调用返回

三,。如果发生超时,请运行循环的主体代码。如果数据显示在管道上,则终止


四,。若要终止,请将数据发送到命名管道

除非你做了一些奇怪的改变,否则睡眠功能应该早起,收到信号后立即返回。然后,您可以在每次睡眠后更改循环以检查$continue标志,以查看是否收到关机信号。

除非您做了一些奇怪的更改,否则睡眠功能应该很早醒来,并在收到信号时立即返回。然后,您可以在每次睡眠后更改循环以检查$continue标志,以查看是否收到关机信号。

如果发送SIGALRM,睡眠调用会发生什么情况?它会停止。。我不知道如果你发送SIGALRM睡眠电话会怎么样?它会停止。。我不知道。如果我采用这种方法,我会反转$sleeptime和$sleepsegment的交互,使$sleepsegment是每个段的持续时间,而不是段数。因为OP关注的是反应能力,所以最好根据需要进行5秒钟的睡眠,而不是将睡眠分成5个部分,因为OP希望能够设置几个小时的睡眠时间,如果这是它决定应该做的。@DaveSherohman我也在想,但选择它是为了易于阅读和代码紧凑。这正是我不想做的。我想要一个能持续数小时的睡眠,我想在接到命令时立即停止。换句话说,我想中断睡眠。@jurgen然后使用我提到的另一种方法,结合SIGALRM,因为这将中断睡眠。相应地编辑了我的答案。编辑您的开始/停止脚本以发送信号,并编辑此脚本以执行此操作。除了您已有的脚本之外,如果我采用此方法,我将反转$sleeptime和$sleepsegment的交互,以便$sleepsegment是durati
每段的长度,而不是段数。因为OP关注的是反应能力,所以最好根据需要进行5秒钟的睡眠,而不是将睡眠分成5个部分,因为OP希望能够设置几个小时的睡眠时间,如果这是它决定应该做的。@DaveSherohman我也在想,但选择它是为了易于阅读和代码紧凑。这正是我不想做的。我想要一个能持续数小时的睡眠,我想在接到命令时立即停止。换句话说,我想中断睡眠。@jurgen然后使用我提到的另一种方法,结合SIGALRM,因为这将中断睡眠。相应地编辑了我的答案。编辑启动/停止脚本以发送SIGALRM,并编辑此脚本以执行此操作。除了您已有的脚本之外,我不会将其称为解决方案,如果您有任何IO需要监控,则在任何情况下都可以睡眠,这是一个更好的解决方案。我不会将其称为解决方案,如果你有任何IO需要监控,那么在任何情况下睡觉都是一个更好的解决方案。它会自己醒来。。哇,我现在觉得自己很愚蠢。你不会碰巧知道如何杀死一个我用系统调用启动的程序吧?也许有一件简单的事情我也忽略了。@jurgen-同样的方式:给它发个信号。SIGINT INTERRUP(相当于按Ctrl-C)是最明显的选择,或者SIGKILL(如果您需要它立即停止而没有机会进行任何清理),这可能是个坏主意。@jurgen系统在您启动的程序退出之前不会返回。所以你不能停止一个你从它开始的程序,因为它已经停止了。我想用kill来终止这个程序,但我确实需要PID来完成,系统没有返回它。在谷歌搜索之后,我发现了一些使用fork+exec技巧获取PID的代码。还没有测试过,但看起来不错。基本上,您只需在if中fork并返回子PID,else块执行exec。然后调用方可以使用waitpid阻塞,直到完成。当一个信号进来时,你可以直接关闭pid。我希望它能工作,星期一会测试。它会自己醒来。。哇,我现在觉得自己很愚蠢。你不会碰巧知道如何杀死一个我用系统调用启动的程序吧?也许有一件简单的事情我也忽略了。@jurgen-同样的方式:给它发个信号。SIGINT INTERRUP(相当于按Ctrl-C)是最明显的选择,或者SIGKILL(如果您需要它立即停止而没有机会进行任何清理),这可能是个坏主意。@jurgen系统在您启动的程序退出之前不会返回。所以你不能停止一个你从它开始的程序,因为它已经停止了。我想用kill来终止这个程序,但我确实需要PID来完成,系统没有返回它。在谷歌搜索之后,我发现了一些使用fork+exec技巧获取PID的代码。还没有测试过,但看起来不错。基本上,您只需在if中fork并返回子PID,else块执行exec。然后调用方可以使用waitpid阻塞,直到完成。当一个信号进来时,你可以直接关闭pid。我希望它能工作,星期一会测试。