apue 第十三章 守护进程
2015-07-31 14:47
399 查看
守护进程的编程规则:
总体来说:没有控制终端(不会接收到使守护进程终止的信号),那么就要调用setsid使进程成为会话首进程,调用setsid的前提条件是该进程不是进程组组长,因此先fork一次,让父进程退出,子进程继续干活
1、调用umask将(继承而来的)创建文件屏蔽字设为一个已知值
2、fork,留下子进程,调用setsid。子进程成为孤儿进程,以及会话首进程
3、为了防止再次关联终端,再次调用fork,使最终的守护进程不是会话首进程,这里,因为会话首进程的退出会向会话中所有的进程发送SIGHUP信号,因此,再次调用fork之前先屏蔽SIGHUP(不知道这里关于屏蔽SIGHUP的理解对不对,我猜是对的)
4、调用chdir将工作目录改为根目录或者某个指定的工作目录
5、关闭不需要的文件描述符
图13_7程序:
创建一个线程调用sigwait来等待SIGHUP和SIGTERM,然后重新读取配置文件
这里产生一个疑惑:在创建线程前,主线程调用pthread_sigmask屏蔽所有信号,那么创建的线程会不会继承这个信号屏蔽字,傻傻的分不清,写个段代码验证
1、这里在主线程中屏蔽除了SIGQUIT、SIGUSR1外的所有信号,运行中可以捕捉到这两个信号
2、创建线程中,如果不调用pthread_sigmask解除对SIGINT、SIGTSTP、SIGUSR2的阻塞,是不会捕捉到信号的,也就是说,主线程在调用pthread_create 之前设置的信号屏蔽字会被创建线程继承
3、在主线程中解除对SIGINT、SIGTSTP,创建线程则捕捉信号成功
多线程下慎用sigwait
http://blog.chinaunix.net/uid-23629988-id-199153.html 关于sigwait函数会被其他信号中断,要判断返回值是不是EINTR
帖子里提到:sigwait这个函数很奇怪,跟一般的linux API不同。sigwait出错的时候,并不设置errno,而直接把errno错误值返回。
把书翻了一下,发现不是sigwait奇怪,而是在多线程的API中,好想是如果成功时返回0的话,那么失败时就会返回错误编号。
对于某些造成阻塞的API:在其返回错误时,要判断是不是EINTR,如果是的话,重启
总体来说:没有控制终端(不会接收到使守护进程终止的信号),那么就要调用setsid使进程成为会话首进程,调用setsid的前提条件是该进程不是进程组组长,因此先fork一次,让父进程退出,子进程继续干活
1、调用umask将(继承而来的)创建文件屏蔽字设为一个已知值
2、fork,留下子进程,调用setsid。子进程成为孤儿进程,以及会话首进程
3、为了防止再次关联终端,再次调用fork,使最终的守护进程不是会话首进程,这里,因为会话首进程的退出会向会话中所有的进程发送SIGHUP信号,因此,再次调用fork之前先屏蔽SIGHUP(不知道这里关于屏蔽SIGHUP的理解对不对,我猜是对的)
4、调用chdir将工作目录改为根目录或者某个指定的工作目录
5、关闭不需要的文件描述符
图13_7程序:
创建一个线程调用sigwait来等待SIGHUP和SIGTERM,然后重新读取配置文件
这里产生一个疑惑:在创建线程前,主线程调用pthread_sigmask屏蔽所有信号,那么创建的线程会不会继承这个信号屏蔽字,傻傻的分不清,写个段代码验证
1、这里在主线程中屏蔽除了SIGQUIT、SIGUSR1外的所有信号,运行中可以捕捉到这两个信号
2、创建线程中,如果不调用pthread_sigmask解除对SIGINT、SIGTSTP、SIGUSR2的阻塞,是不会捕捉到信号的,也就是说,主线程在调用pthread_create 之前设置的信号屏蔽字会被创建线程继承
3、在主线程中解除对SIGINT、SIGTSTP,创建线程则捕捉信号成功
#include <apue.h> #include <signal.h> void sig_inter(int signo) { printf("receive SIGINT\n"); } void sig_tstp(int signo) { printf("receive SIGTSP\n"); } void sig_quit(int signo) { printf("receive SIGQUIT\n"); } void sig_usr1(int signo) { printf("receive SIGUSR1\n"); } void sig_usr2(int signo) { printf("receive SIGUSR2"); } void *thr_fn(void *arg) { sigset_t set; struct sigaction sa_intr,sa_tstp; sa_intr.sa_handler=sig_inter; sa_tstp.sa_handler=sig_tstp; sigemptyset(&set); sigfillset(&set); sigdelset(&set,SIGINT); sigdelset(&set,SIGTSTP); //pthread_sigmask(SIG_SETMASK,&set,NULL); sa_intr.sa_mask=set; sa_intr.sa_flags=0; sa_tstp.sa_mask=set; sa_tstp.sa_flags=0; if(sigaction(SIGINT,&sa_intr,NULL)<0) err_sys("%ld: sigaction error",pthread_self()); if(sigaction(SIGTSTP,&sa_tstp,NULL)<0) err_sys("%ld: sigaction error",pthread_self()); sa_intr.sa_handler=sig_usr2; if(sigaction(SIGUSR2,&sa_intr,NULL)<0) err_sys("%ld: sigaction error",pthread_self()); while(1) sleep(2); } int main() { sigset_t mask; sigemptyset(&mask); sigaddset(&mask,SIGUSR1); sigaddset(&mask,SIGUSR2); sigprocmask(SIG_BLOCK,&mask,NULL); sigset_t set; sigemptyset(&set); //sigaddset(&set,SIGINT); //sigaddset(&set,SIGTSTP); sigfillset(&set); sigdelset(&set,SIGQUIT); sigdelset(&set,SIGUSR1); sigdelset(&set,SIGINT); sigdelset(&set,SIGTSTP); pthread_sigmask(SIG_SETMASK,&set,NULL); struct sigaction sa; sa.sa_handler=sig_quit; sa.sa_flags=0; sa.sa_mask=set; if(sigaction(SIGQUIT,&sa,NULL)<0) err_sys("%ld: sigaction error",pthread_self()); sa.sa_handler=sig_usr1; if(sigaction(SIGUSR1,&sa,NULL)<0) err_sys("%ld: sigaction error",pthread_self()); pthread_t tid; if((tid=pthread_create(&tid,NULL,thr_fn,NULL))!=0) { err_sys("pthread_create error"); } while(1) sleep(2); }
多线程下慎用sigwait
http://blog.chinaunix.net/uid-23629988-id-199153.html 关于sigwait函数会被其他信号中断,要判断返回值是不是EINTR
帖子里提到:sigwait这个函数很奇怪,跟一般的linux API不同。sigwait出错的时候,并不设置errno,而直接把errno错误值返回。
把书翻了一下,发现不是sigwait奇怪,而是在多线程的API中,好想是如果成功时返回0的话,那么失败时就会返回错误编号。
对于某些造成阻塞的API:在其返回错误时,要判断是不是EINTR,如果是的话,重启
相关文章推荐
- UUID
- 延迟队列DelayQueue的使用示例
- ubuntu x64安装jd-gui
- VirtualBox安装VBoxGuestAdditions增强功能
- Codeforces Round #287 (Div. 2) C. Guess Your Way Out! 二叉树遍历
- request.getScheme()的使用方法
- iOS UItableView通讯录
- easyUI验证validatebox
- 关于Android Stduio插件的问题
- UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
- UI02_UIButton
- BlueDBM个人读感
- iOS-UI-07 代理的使用
- c# request了解一下
- HDOJ丶 1005(Number Sequence)
- error MSB8031 Building an MFC project for a non-Unicode character set is deprecated
- QT下ui类的this指针与ui指针
- guava (四)--集合中的FluentIterable类
- [XCode] XCode 6 中 UIPickerView 的简单示例
- 【iOS开发系列】物理仿真动画UIDynamic (1)