【C】——利用sigsuspend函数等待信号阻塞进程
2013-10-21 16:56
519 查看
#include<signal.h> int sigsuspend(const sigset_t *sigmask); 返回值:-1,并将errno设置为EINTR
将进程的信号屏蔽字设置为由sigmask指向的值,在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程被挂起。
例子:
利用sigsuspend函数阻塞子进程;
#include<stdio.h> #include<stdlib.h> #include<signal.h> #include<unistd.h> sig_atomic_t sigflag; sigset_t newmask,oldmask,zeromask; void sig_int(int signo) { sigflag = 1; } void tell_wait(void) { sigflag = 0; if(signal(SIGUSR1,sig_int) == SIG_ERR){ printf("signal error!\n"); exit(1); } printf("after signal!\n"); /* sigemptyset(&newmask); sigemptyset(&zeromask); sigaddset(&newmask,SIGINT); if(sigprocmask(SIG_BLOCK,&newmask,&oldmask) < 0){ printf("sigprocmask error!\n"); exit(1); } */ } void tell_child(pid_t pid) { kill(pid,SIGUSR1); } void wait_parent(void) { while(sigflag == 0) sigsuspend(&zeromask); sigflag = 0; if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){ printf("sigprocmask erro!\n"); exit(1); } } int main(int argc, char *argv[]) { pid_t pid; printf("before signal!\n"); tell_wait(); if((pid = fork()) < 0){ printf("fork error!\n"); exit(1); } else if(pid == 0){ wait_parent(); printf("this is child!\n"); exit(0); } else{ printf("this is parent!\n"); tell_child(pid); } exit(0); }
例子中的sigprocmask函数是用来检测或更改其信号屏蔽字,或者在一个步骤中同时执行这两个操作。
#include<signal.h> int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset); //返回值:成功返回0,出错返回-1
how: SIG_BLOCK SIG_UNBLOCK SIG_SETMASK
sigprocmask配合sigpending函数使用,
#include<signal.h> int sigpending(sigset_t *set); //返回值:成功返回0,出错返回-1
sigpending函数:查询被搁置的信号!
其实sigsuspend是一个原子操作,包含4个步骤:
(1) 设置新的mask阻塞当前进程;
(2) 收到信号,恢复原先mask;
(3) 调用该进程设置的信号处理函数;
(4) 待信号处理函数返回后,sigsuspend返回。
pause函数和sigsuspend函数的区别:
简单的说, sigsuspend = unblock + pause
sigsuspend 函数是用于需要先接触 某个信号的阻塞状态 然后等待该信号发生 这样的应用场景; 而使用 pause 在达到这样的效果时肯定是需要先 调用sigprocmask进行取消阻塞,再调用pause去等待,取消阻塞与等待两步之间有时间窗口,在信号发生在调用pause之前任意时刻的话都有可能导致pause之后再也收不到该信号,也就是永远休眠。为了解决这种情况,sigsuspend函数把这两步做成一个原子操作,这就保证不会丢失(错过)信号,也就不会发生永远休眠这种情况(根本不发生该信号时除外)。所以,建议只用sigsuspend去等待信号。
相关文章推荐
- 信号注册函数回收子进程,waitpid非阻塞回收
- wait()函数,作用:阻塞等待任意子进程,回收子进程8kb物理内存
- 线程共享的环境包括:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。 进程拥有这
- linux系统编程之信号(五):信号集操作函数,信号阻塞与未决
- 信号解除阻塞后进程是否立刻收到信号
- 【经典转载】Linux进程学习系列之五 等待进程结束wait()和waitpid()函数
- Linux子进程的异步等待方式(SIGCHLD信号)
- 网络编程(13)—— 利用信号处理函数signal和sigaction销毁僵尸进程
- 当子进程结束的时候,其设置的信号捕捉函数不会再父进程生效
- linux进程通信---几个发送信号的函数(kill,raise,alarm,pause)
- C程序完成:父进程创建一个子进程,父进程对子进程设置一个报警信号,然后父进程等待子进程的结束,如果此时报警信号先到,就终止子进程。
- Socket send函数和recv函数详解以及利用select()函数来进行指定时间的阻塞【转】
- Delphi写的等待进程运行结束函数
- 信号实现等待另一个进程
- sigsuspend 用于等待信号处理程序设置全局变量
- shell命令管道未读完阻塞了子进程,与等待其结束的父进程死"锁"。
- Linux多进程——利用fork()函数进行多进程编程
- linux系统编程之信号(五):信号集操作函数,信号阻塞与未决
- 函数: waitpid - 等待子进程中断或结束
- 利用mmap函数实现多进程文件拷贝