分类:
2009-05-25 10:59:05
/* 利用信号实现父子进程通信(传递信息)和同步,author by bob
#include
#include
#include
void sig_usr2(int signo,siginfo_t *info,void *myact)
{
printf("signo = %d\n",signo);
printf("child process has sent its signal \n");
}
int main(void)
{
sigset_t wait_set;
int sig_no;
const struct timespec tv = {5,0}; //timeout
siginfo_t sig_info ;//传递的信息结构
pid_t pid = 0;
sigemptyset(&wait_set);
sigaddset(&wait_set,SIGUSR2);
signal(SIGCHLD,SIG_IGN); //父进程显式的忽略子进程发来的SIGCHLD信号 ,防止出现Zombie 进程,如果忘记了,复习一下上面!
pid = fork();
if(pid < 0) {
printf("fork failure \n");
exit(-1);
}
if(pid == 0) {
int rc = 0;
union sigval rc_val; //子进程要传递的信息
setsid();
umask(0);
chdir("/");
rc = system("curl -O &>/dev/null");
printf("rc = %d\n",rc);
rc_val.sival_int = rc/255; //传递整型值
if(getppid() > 1) { //因为如果过了timeout , 父进程就退出了, 该子进程被init(1)领养, 所以千万不要向init(1)发信号!否则整个系统都要reboot 了!
sigqueue(getppid(),SIGUSR2,rc_val);//给父进程发信号!,getppid()可以获得父进程的pid
}
exit(0);
}
//parent process
again:
sigprocmask(&wait_set);
sig_no = sigtimedwait(&wait_set,&sig_info,&tv); //父进程会一直阻塞tv时间,然后就返回
if(sig_no == -1) { //说明超时
if(errno == EINTR) //表示被别的信号给中断了
{
goto again; //重新调用sigwaitinfo() 继续等待
else if(errno == EAGAIN); //如果你用的是sigtimedwait()函数,这个也许有用,表示在规定的timeout时间无法获得资源, errno== EAGAIN
printf("child process timeout \n");
printf("curl 一直没有返回,这样下载看起来没有问题, 正在下载\n");
}
}
else {
printf("child process return value = %d\n",sig_info.si_int);
if(sig_info.si_int == 0) //信号传递的信息! 我们在这里传递integer值!
printf("下载完毕\n");
else
printf("下载出错,错误代码 %d\n", sig_info.si_int);
}
return 0;
}
*/