一起talk C栗子吧(第八十六回:C语言实例--使用信号进行进程间通信三)


各位看官们,大家好,上一回中咱们说的是进程间通信的例子,这一回咱们接着上一回的内容,继续说该例子。闲话休提,言归正转。让我们一起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            //子进程运行结束

各位看官,关于使用信号进行进程间通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

talk_8

真诚赞赏,手有余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值