Linux学习之进程通信(信号的接收与信号的处理)

言之者无罪,闻之者足以戒。 ——《诗序》

二、信号的接收

接收信号的进程,需要的条件:要想使接收的进程能收到信号,这个进程就不能结束

接收信号的函数:sleep()、while(1)、pause()

sleep()函数使进程进入睡眠状态(S)

pause()函数使进程进入睡眠状态(S)

while(1)函数使进程一直在运行(R状态)

sleep()和while(1)都非常简单,上面的程序我们都已经使用过了,现在来说一下pause()函数,其实pause()函数也很简单。它没有入口参数,返回值也很简单,下面我们来看一下:

所需头文件

#include <unistd.h>

函数原型

int pause(void);

函数返回值

成功:0,出错:-1

   下面给出关于pause函数的程序:

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
int main()
{
        int i=0;
        printf("pause befor\n");
        pause();
        printf("pause after\n");
        return 0;
}

三、信号的处理

收到信号的进程,应该怎样处理?处理的方式有哪些?

(1)进程的默认处理方式(内核为用户进程设置的默认处理方式)

A:忽略

B:终止进程

C:暂停

(2)自己的处理方式:

自己处理信号的方法告诉内核,这样你的进程收到了这个信号就会采用你自己的处理方式

1、signal函数:

void (*signal(int signum, void (*handler)(int)))(int);

signal函数有两个参数:

第一个参数:是一个整形变量(信号值)

第二个参数:是一个函数指针,是我们自己写的处理函数

返回值:是一个函数指针

所需头文件

#include <signal.h>

函数原型

void (*signal(int signum, void (*handler)(int)))(int);

函数传入值

signum:指定信号

 

handler 

SIG_IGN:忽略该信号。

 

 

SIG_DFL:采用系统默认方式处理信号。

 

 

自定义的信号处理函数指针

函数返回值

成功:设置之前的信号处理方式

 

出错:-1

下面给出一段程序:

include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
void myfun(int signum)
{
        int i=0;
        while(i < 6)
        {
                printf("process signal signum=%d\n",signum);
                sleep(1);
                i++;
        }
        return;//return main
}
int main()
{
        int i=0;
        signal(14,myfun);
        printf("pause befor\n");
        alarm(8);
        printf("pause after\n");
        while(i < 20)
        {
                printf("process working time is %d\n",i);
                i++;
                sleep(1);
        }
        return 0;
}

上面我们说了handler参数形式有三种,第三种我们已经演示过了下面演示一下第一种和第二种:

第一种程序代码:

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
void myfun(int signum)
{
        int i=0;
        while(i < 6)
        {
                printf("process signal signum=%d\n",signum);
                sleep(1);
                i++;
        }
        return;//return main
}
int main()
{
        int i=0;
        signal(14,myfun);
        printf("pause befor\n");
        alarm(8);
        printf("pause after\n");
        signal(14,SIG_IGN);
        while(i < 20)
        {
                printf("process working time is %d\n",i);
                i++;
                sleep(1);
        }
        return 0;
}

第二种程序代码:
 

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
void myfun(int signum)
{
        int i=0;
        while(i < 6)
        {
                printf("process signal signum=%d\n",signum);
                sleep(1);
                i++;
        }
        return;//return main
}
int main()
{
        int i=0;
        signal(14,myfun);
        printf("pause befor\n");
        alarm(8);
        printf("pause after\n");
        signal(14,SIG_IGN);
        signal(14,SIG_DFL);
        while(i < 20)
        {
                printf("process working time is %d\n",i);
                i++;
                sleep(1);
        }
        return 0;
}

下面我们写一段程序来实现一下的功能:

(1)子进程sleep(10)之后向父进程发送一个信号

(2)父进程接收信号之后,按照自己定义的方式处理信号

(3)再sleep(10)之后再一次向父进程发送一个信号

(4)父进程接收信号之后,按照自己定义的第二种方式处理信号

#include "stdio.h"
#include "sys/types.h"
#include "signal.h"
#include "stdio.h"
#include "stdlib.h"
void myfun(int signum)
{
        int i=0;
        while(i < 5)
        {
                printf("receive signum=%d,i=%d\n",signum,i);
                sleep(1);
                i++;
        }
        return ;
}
void myfun1(int signum)
{
        printf("receive signum=%d\n",signum);
        wait(NULL);
        return;
}
int main()
{
        pid_t pid;
        pid=fork();
        if(pid >0)
        {
                int i=0;
                signal(10,myfun);
                signal(17,myfun1);
                while(1)
                {
                        printf("parent process things ,i=%d\n",i);
                        sleep(1);
                        i++;
                }
        }
        if(pid == 0)
        {
                sleep(10);
                kill(getppid(),10);
                sleep(10);
                exit(0);
        }
        return 0;
}

到这为止,关于信号通信方面的知识就已经说完了。

 

 

猜你喜欢

转载自blog.csdn.net/weixin_42994525/article/details/83046383