Mat*_*att 1 c linux signals pthreads
我正在尝试编写一个信号处理程序来捕获任意数量的连续SIGINT信号并阻止程序退出.该程序是一个简单的文件服务器.处理程序设置一个全局标志,导致while循环接受新连接结束,对pthread_exit()的调用确保main允许当前连接在退出之前完成.当我点击ctrl-C一次但第二次立即退出程序时,这一切都像发条一样.
我首先尝试使用signal():
signal(SIGINT, catch_sigint);
...
static void catch_sigint(int signo)
{
...
signal(SIGINT, catch_sigint);
}
Run Code Online (Sandbox Code Playgroud)
我也尝试使用sigaction:
struct sigaction sigint_handler;
sigint_handler.sa_handler = catch_sigint;
sigemptyset(&sigint_handler.sa_mask);
sigint_handler.sa_flags = 0;
sigaction(SIGINT, &sigint_handler, NULL);
Run Code Online (Sandbox Code Playgroud)
不确定如何"重新安装"这个我只是在处理程序中复制此代码类似于使用signal()方法的处理程序.
这些都不像我预期的那样有效.
附加信息:
该程序是一个简单的文件服务器.它接收来自客户端的请求,该请求只是一个由请求的文件名组成的字符串.它利用pthreads,以便可以同时进行传输.收到SIGINT后,我希望服务器退出while循环并等待所有当前传输完成然后关闭.原样,无论我如何编码信号处理程序,第二个SIGINT立即终止程序.
int serverStop = 0;
...
int main()
{
/* set up the server -- socket(), bind() etc. */
struct sigaction sigint_hadler;
sigint_handler.sa_handler = catch_sigint;
sigint_handler.sa_flags = 0;
sigemptyset(&sigint_handler.sa_mask);
sigaction(SIGINT, &sigint_handler, NULL);
/* signal(SIGINT, catch_sigint); */
while(serverStop == 0)
{
/* accept new connections and pthread_create() for each */
}
pthread_exit(NULL);
}
...
static void catch_sigint(int signo)
{
serverStop = 1;
/* signal(SIGINT, catch_sigint) */
}
Run Code Online (Sandbox Code Playgroud)
我不认为任何其他代码可能是相关的,但可以随意要求详细说明
在Linux上,您不必使用任何一个signal(默认情况下实现BSD语义)或重新安装信号处理程序sigaction.
当我按下ctrl-C一次,但第二次立即退出程序.
这不是因为你的处理程序被重置,但可能是因为你的信号处理程序正在做一些它不应该做的事情.
以下是我将如何调试此问题:在GDB下运行程序
(gdb) catch syscall exit
(gdb) catch syscall exit_group
(gdb) run
Run Code Online (Sandbox Code Playgroud)
现在等待程序开始工作,然后点击Control-C.这会给你(gdb)提示.现在继续该程序,就像它已收到SIGINT:( signal SIGINT这将调用您的处理程序).再次重复'Control-C/signal SIGINT'序列.如果您在系统调用exit或exit_group系统调用中停止,请查看它的来源(使用GDB where命令).
更新:
鉴于您发布的新代码,目前尚不清楚您在何处调用pthread_exit"确保主要允许当前连接在退出之前完成".由于写的,你的主线程将退出在第一控制-C循环,并继续呼吁exit这将不会等待其它线程完成.
要么你没有显示你的实际代码,要么"第二个Control-C"是一个红色的鲱鱼,你的第一个Control-C已经把你带走了(没有完成其他线程的工作).
| 归档时间: |
|
| 查看次数: |
1370 次 |
| 最近记录: |