各位看官们,大家好,上一回中咱们说的是进程间通信的例子,这一回咱们接着上一回的内容,继续说该例子。闲话休提,言归正转。让我们一起talk C栗子吧!
看官们,我们在上一回中说到了signal函数的缺点,从而引出了sigaction函数,它比signal函数要健壮一些,接下来我们介绍它的用法。
sigaction函数的和signal函数的作用类似:用来配置信号处理函数。不过,他的配置性要强大很多。
下面是sigaction的函数原型:
int sigaction(int sig,const struct sigaction *act,struct sigaction *oact)
大家看到这个函数是不觉得有些复杂了呢,不用担心,我们慢慢分析它:
它有三个参数
- 第一个参数sig表示需要配置的信号;
- 第二个参数表示对信号的详细配置国;
- 第三个参数用来存放信号被配置以前的动作,如果没有这个需要,可以为空。
- 该函数运行成功时返回0,失败时返回-1.
该函数中最后两个 参数是struct sigaction类型的指针,下面是该结构体的定义,以及每个成员的作用:
struct sigaction
{
void (*sa_handler)(int); //信号处理函数,和signal函数中的func对应
sigset_t sa_mask; //信号集,参数sig代表的信号会加入到该信号集中
int sa_flags; //表示对信号的处理方式,通常为0
void (*sa_sigaction)(int,siginfo_t *,void *); //和第一个成员作用类似,当sa_flags为SA_SIGINFO时,
//使用该函数处理信号,而不使用sa_handler指向的函数处理信号
};
大家从上面的结构体定义中可以看到对信号的配置和处理都放到了sigaction的第二个参数act中,所以
我们可以修改参数act的值,来满足对信号配置的要求。
接下来,我们通过具体的代码来说明它们的用法。
#include<unistd.h>
#include<signal.h>
#include<stdio.h>
// signal process function
void sig_receive(int signo)
{
printf("received signal :%d \n",signo);
printf("signalprocessing in :%d \n",getpid());
// do something for signal
}
int main()
{
pid_t pid;
int pid_res;
int stat_value;
struct sigaction act;
act.sa_handler = sig_receive; //config the signal processing function
sigemptyset(&act.sa_mask); //config the signal set,and it will be setted as empty
act.sa_flags = 0; // do need to give a value to it
sigaction(SIGALRM,&act,NULL); //config signal by sigaciton function, the third param is NULL
pid = fork();
if(pid > 0)
{
printf("PID: %d -> Father Process send signal\n",getpid());
kill(pid,SIGALRM); //send signal
}
else if(pid == 0)
{
printf("PID: %d -> Son Process receive signal \n",getpid());
}
else
{
printf("Create process failed \n");
return 1;
}
pid_res = wait(&stat_value);
if(pid_res > 0)
{
printf("Son process finished: PID = %d \n",pid_res);
}
return 0;
}
从上面的代码中,我们可以看到:首先配置sigaction的参数,具体的操作如下:
- 给信号配置信号处理函数;
- 接着设置信号集;
- 最后通过sigaction函数配置信号处理函数。
大家可以和前一章回中的内容进行对比,我们使用sigaction函数取代了signal函数,该函数可以把信号放到进程的信号集中,阻塞起来,直到信号处理函数准备好时,再让进程接收信号。这样可以避免信号处理函数还没有被调用就收到了信号。
看官们,正文中就不写代码了,详细的代码放到了我的资源中,大家可以点击这里下载使用。
下面是程序的运行结果,请大家参考:
PID: 4468 -> Father Process send signal //父进程发送信号
received signal :14 //信号处理函数在处理信号
signalprocessing in :4469 //信号处理函数在处理信号
PID: 4469 -> Son Process receive signal
Son process finished: PID = 4469 //子进程运行结束
各位看官,关于使用信号进行进程间通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。