一起talk C栗子吧(第八十六回:C语言实例--使用

页面导航:首页 > 软件编程 > C 语言 > 一起talk C栗子吧(第八十六回:C语言实例--使用

一起talk C栗子吧(第八十六回:C语言实例--使用

来源: 作者: 时间:2016-01-15 10:00 【

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

// 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            //子进程运行结束

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



Tags:

文章评论

最 近 更 新
热 点 排 行
Js与CSS工具
代码转换工具

<