6.1 信号二、守护进程2015/7/30
来源:互联网 发布:check it out 编辑:程序博客网 时间:2024/06/05 05:19
信号
SIGCHLD信号处理
SIGCHLD的产生条件
子进程终止时子进程收到SIGSTOP信号停止时子进程处在停止态,接收到SIGCONT后唤醒时
例:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <sys/stat.h>#include <sys/types.h>#include <signal.h>void sys_err(const char *str){ perror(str); exit(1);}void do_sig_child(int signo){ int status; pid_t pid; while ((pid = waitpid(0, &status, WNOHANG)) > 0) { /* No blocking recycling process*/ if (WIFEXITED(status)) /* normal exit */ printf("child %d exit %d\n", pid, WEXITSTATUS(status)); else if (WIFSIGNALED(status)) /* signal make quit */ printf("child %d cancel signal %d\n", pid, WTERMSIG(status)); /* which signal */ } }int main(void){ pid_t pid; int i; /* block SIGCHLD*/ for (i=0; i<10; i++) { //子进程,就跳出循环 父进程继续生成子进程,10次 if ((pid = fork()) == 0) break; else if (pid < 0) sys_err("fork"); } if (pid == 0) { int n = 18; while (n--) { printf("child ID %d\n", getpid()); sleep(1); } return i; } else if (pid > 0) { /* 1.set handler */ /* 2.remove SIGCHLD block */ struct sigaction act; act.sa_handler = do_sig_child; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGCHLD, &act, NULL); //if child dead,it will set SIGCHLD while (1) { printf("Parent ID %d\n", getpid()); sleep(1); } } return 0;}
信号不支持排队,当执行捕捉函数,收到多个信号时,在未决信号集里面只有一个,所以要用while循环回收。
status处理方式
pid_t waitpid(pid_t pid, int *status, int options) options WNOHANG 没有没有子进程结束,立即返回(非阻塞) WUNTRACED 如果子进程由于被停止产生的SIGCHLD, waitpid则立即返回 WCONTINUED 如果子进程由于被SIGCONT唤醒而产生的SIGCHLD,waitpid则立即返回 获取status WIFEXITED(status) 子进程正常exit终止,返回真 WEXITSTATUS(status)返回子进程正常退出值 WIFSIGNALED(status) 子进程被信号终止,返回真 WTERMSIG(status)返回终止子进程的信号值 WIFSTOPPED(status) 子进程被停止,返回真 WSTOPSIG(status)返回停止子进程的信号值 WIFCONTINUED(status) 子进程有停止态转为就绪态,返回真
信号中断系统调用
read阻塞时,信号中断系统调用1.返回部分读到的数据2.read调用失败,errno设成EINTER
守护进程
Daemon(精灵)进程,是linux中的后台服务进程,生存期较长的进程,通常独立于终端并且周期性执行某种任务或等待处理某些发生的事件
模型
守护进程编程步骤
1.创建子进程,父进程退出
所有工作在子进程中进行
形式上脱离了控制终端
2.在子进程中创建新会话
setsid()函数
使子进程完全独立出来,脱离控制
3.改变当前目录为根目录
chdir()函数
防止占用可卸载的文件系统
也可以换成其他路径
4.重设文件权限掩码
umask()函数
防止继承的文件创建屏蔽字拒绝某些权限
增加守护进程灵活性
5.关闭文件描述符0,1,2
继承的打开文件不会用到,浪费系统资源,无法卸载
6.开始执行守护进程核心工作
7.守护进程退出处理
代码模型
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>void daemonize(void){ pid_t pid; /* *成为一个新会话的首进程,失去控制终端 */ if((pid = fork()) < 0) { perror("fork"); exit(1); } else if (pid != 0) /* parent */ exit(0); setsid(); /* 改变当前工作目录到/目录下 */ if(chdir("/") < 0) { perror("chdir"); exit(1); } /* 设置umask为0 */ umask(0); /* 重定向0,1,2文件描述符到 /dev/null,因此已经失去控制终端,再操作0,1,2没有意>义*/ close(0); open("/dev/null", O_RDWR); dup2(0, 1); dup2(0, 2);}int main(void){ daemonize(); while(1) sleep(1);}
0 0
- 6.1 信号二、守护进程2015/7/30
- 守护进程二
- linux高编之信号守护进程
- 创建守护进程并且接收信号
- Linux信号处理和守护进程
- 守护进程例子(二)
- python daemon 守护进程对信号的处理
- Linux守护进程加上发送信号固定模式
- C语言实现简单的守护进程及信号处理
- linux多进程——进程组与会话、守护进程、信号通信
- linux多进程——进程组与会话、守护进程、信号通信
- linux多进程——进程组与会话、守护进程、信号通信 .
- 守护进程守护自身
- 守护线程、守护进程
- 6.1 守护进程课后题2015/8/1
- 守护进程
- 守护进程
- 守护进程
- measure_bga_dff.hdev焊点bga封装的高度 相关例程学习
- 4G网络技术及应用
- android-lisiview-adapter
- AndroidManifest.xml文件详解(supports-screens)
- CTreeCtrl中的SetItemState函数的使用
- 6.1 信号二、守护进程2015/7/30
- MyEclipse建立SpringMVC入门HelloWorld项目
- CATransition 转场动画
- nyoj 79拦截导弹
- Copy On Write(写时复制)
- [MySQL FAQ]系列 — 怎么计算打开文件数
- 关于隐性intent的一些疑惑与解释
- nyoj325 zb的生日(DFS)
- MySQL提示:The server quit without updating PID file(…)失败的一些解决方法