免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4652 | 回复: 7
打印 上一主题 下一主题

[C] 用execl函数实现程序重启的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-01-11 00:42 |只看该作者 |倒序浏览
10可用积分
程序想实现的功能就是捕捉到SIGINT信号的时候重新启动,然后再捕捉到的时候再次重新启动。
exec函数执行的时候用一个全新的程序代替当前进程的数据段,堆栈和正文段。
在这里信号处理函数sig_handler中执行execl(PWD, "a.out", (char* )0)的时候,可执行程序a.out
代替了当前进程的数据段,堆栈和正文段,使程序重新运行
但是执行的时候:
./a.out
hello, program starting!
1111111111111111111111111                                      按ctrl+c
hello, caught SIGINT signal in sig_handler function!
hello, program starting!
1111111111111111111111111                                      重启后按ctrl+c后无法调用信号处理程序



  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <unistd.h>

  5. #define PWD     "/home/xxxx/my_test/algorithm/c_expert/chap7/a.out"
  6. static void sig_handler(int signo);

  7. int main(int argc, char** argv)
  8. {
  9.         struct sigaction                act, oact;

  10.         printf("hello, program starting!\n");
  11.         act.sa_handler = sig_handler;
  12.         sigemptyset(&act.sa_mask);
  13.         act.sa_flags = 0;
  14.         if(sigaction(SIGINT, &act, &oact) == -1){
  15.                 perror("sigaction error");
  16.                 exit(1);
  17.         }
  18. printf("1111111111111111111111111\n");
  19.         pause();

  20.         exit(0);
  21. }

  22. static void sig_handler(int signo)
  23. {
  24.         printf("hello, caught SIGINT signal in sig_handler function!\n");
  25.         if(execl(PWD, "a.out", (char* )0) == -1){
  26.                 perror("execl error");
  27.                 exit(2);
  28.         }
  29. }
复制代码

最佳答案

查看完整内容

是这样子的, 你在执行sig_handler的时候会屏蔽当前的这个信号, 也就是SIGINT这个信号, 这个以前讨论过的. 那么你从这个sig_handler调用execl的时候, 新的进程会继承原来进程的这个Process signal mask, 即屏蔽了哪些信号. 因此, 你在第二次按ctrl+C的时候由于这个信号被屏蔽掉了, 所以就不会运行信号处理函数. 你可以在pause()前面加上打印出来就可以看到了.[ 本帖最后由 scutan 于 2008-1-11 10:36 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-01-11 00:42 |只看该作者
原帖由 xiaozhu2007 于 2008-1-11 00:42 发表
程序想实现的功能就是捕捉到SIGINT信号的时候重新启动,然后再捕捉到的时候再次重新启动。
exec函数执行的时候用一个全新的程序代替当前进程的数据段,堆栈和正文段。
在这里信号处理函数sig_handler中执行ex ...


是这样子的, 你在执行sig_handler的时候会屏蔽当前的这个信号, 也就是SIGINT这个信号, 这个以前讨论过的.
那么你从这个sig_handler调用execl的时候, 新的进程会继承原来进程的这个Process signal mask, 即屏蔽了哪些信号. 因此, 你在第二次按ctrl+C的时候由于这个信号被屏蔽掉了, 所以就不会运行信号处理函数.

你可以在pause()前面加上

  1.         if (sigprocmask(0, NULL, &sigset) < 0)
  2.         {
  3.                 perror("sigprocemask");
  4.                 exit(0);
  5.         }

  6.         if (sigismember(&sigset, SIGINT))
  7.                 printf("sigalrm is blocked\n");
  8.         else
  9.                 printf("sigalrm is not blocked\n");

复制代码

打印出来就可以看到了.

[ 本帖最后由 scutan 于 2008-1-11 10:36 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2008-01-11 02:57 |只看该作者
是不是重启后a.out不在前台运行了?我不大确定。

论坛徽章:
0
4 [报告]
发表于 2008-01-11 11:19 |只看该作者
把act.sa_flags = 0;修改为act.sa_flags = SA_NODEFER;就可以响应ctr+C了!但是这样会引起嵌套调用,不知道内存会不会一直增加?

论坛徽章:
0
5 [报告]
发表于 2008-01-11 12:05 |只看该作者
原帖由 ljok30 于 2008-1-11 11:19 发表
把act.sa_flags = 0;修改为act.sa_flags = SA_NODEFER;就可以响应ctr+C了!但是这样会引起嵌套调用,不知道内存会不会一直增加?



嗯. 设置那个标志位是可以的.
SA_NODEFER

When this signal is caught, the signal is not automatically blocked by the system while the signal-catching function executes (unless the signal is also included in sa_mask). Note that this type of operation corresponds to the earlier unreliable signals.

内存不会增加.

论坛徽章:
0
6 [报告]
发表于 2008-01-11 16:53 |只看该作者
原帖由 ljok30 于 2008-1-11 11:19 发表
把act.sa_flags = 0;修改为act.sa_flags = SA_NODEFER;就可以响应ctr+C了!但是这样会引起嵌套调用,不知道内存会不会一直增加?


这里不MASK的情况下,按下^c为什么 不一下响应多次?

论坛徽章:
0
7 [报告]
发表于 2008-01-14 13:03 |只看该作者

回复 #2 scutan 的帖子

那么实现重新启动功能的程序一般都采用这种方法写吗?

论坛徽章:
0
8 [报告]
发表于 2008-01-14 13:30 |只看该作者

回复 #7 xiaozhu2007 的帖子

很少程序会自动重启的吧。
我的经验是
1)外部方式: crontab脚本检测程序是否正常运行,或者定时重启(比如apache)
2)内部方式: 程序自身不使得自身重启,而是通过信号触发,进程自身释放所有之前获取的资源,重读配置和其他资源,达到重新启动的目的,这种比较通用,也是配置改变的时候最常用的方式之一。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP