进程间通信——信号

1,什么是信号

信号是软件中断;信号提供了一种处理异步事件的方法:终端用户键入中断键,则会通过信号机构停止一个程序;是一种异步通信方式。

2,信号类型

Linux下查看支持的信号列表,可以直接输入kill -l;
在这里插入图片描述
简要说明;
名称 说明
SIGHUP 终止进程 终端线路挂断
SIGINT   终止进程 中断进程
SIGQUIT   建立CORE文件   终止进程,并且生成core文件
SIGILL   建立CORE文件 非法指令
SIGTRAP   建立CORE文件 跟踪自陷
SIGBUS   建立CORE文件 总线错误
SIGSEGV   建立CORE文件 段非法错误
SIGFPE   建立CORE文件 浮点异常
SIGIOT   建立CORE文件 执行I/O自陷
SIGKILL   终止进程 杀死进程
SIGPIPE   终止进程 向一个没有读进程的管道写数据
SIGALARM   终止进程 计时器到时
SIGTERM   终止进程 软件终止信号
SIGSTOP   停止进程 非终端来的停止信号
SIGTSTP   停止进程 终端来的停止信号
SIGCONT   忽略信号 继续执行一个停止的进程
SIGURG   忽略信号 I/O紧急信号
SIGIO   忽略信号 描述符上可以进行I/O
SIGCHLD   忽略信号 当子进程停止或退出时通知父进程
SIGTTOU   停止进程 后台进程写终端
SIGTTIN   停止进程 后台进程读终端
SIGXGPU   终止进程 CPU时限超时
SIGXFSZ   终止进程 文件长度过长
SIGWINCH   忽略信号 窗口大小发生变化
SIGPROF   终止进程 统计分布图用计时器到时
SIGUSR1   终止进程 用户定义信号1
SIGUSR2   终止进程 用户定义信号2
SIGVTALRM  终止进程 虚拟计时器到时

信号的处理方式有3种

1 忽略(就是不管你发啥我都不理你)
2默认处理方式(会终止一个进程)
3自定义处理方式(通过信号执行自定义函数)

3,signal函数

3,1函数介绍

#include <signal.h>
void (*signal (int signo , void (*func)(int))) (int);

返回:成功则为以前的信号处理配置,若出错则为 SIG_ERR

signal函数的原型说明此函数要求两个参数,返回一个函数指针,而该指针所指向的函数 无返回值(void)。
第一个参数signo是一个整型数,
第二个参数是函数指针,它所指向的函数需 要一个整型参数,无返回值。用一般语言来描述也就是要向信号处理程序传送一个整型参数, 而它却无返回值。当调用signal设置信号处理程序时,第二个参数是指向该函数 (也就是信号处 理程序)的指针。signal的返回值则是指向以前的信号处理程序的指针。

3,2例子

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
int			child_run = 0;
int			parent_run = 0;

void sig_child(int signum)    //子进程信号处理函数
{
	if(SIGUSR1 == signum)
	{
		printf("i am child sig\n");
                child_run = 1;
	}
}

void sig_parent(int signum)     //父进程的信号处理函数
{
	if(SIGUSR2 == signum)
	{
               printf("i am parent sig\n");
               parent_run = 1;
	}
}


int main(int argc, char **argv)
{
	pid_t				pid = -1;
        int			        child_statu;

	//注册信号
        signal(SIGUSR1,sig_child);
	signal(SIGUSR2,sig_parent);

	//创建进程
        pid = fork();
	if(pid < 0)
	{
		printf("creat fork failure\n");
		exit(0);
	}
       
        //子进程
        if(pid == 0)
	{
                printf("creat child fork successful,wait signal..\n");

                while(!child_run)     //阻塞等待父进程发信号
                {
                      sleep(1);

                }
                kill(getppid(),SIGUSR2);//子进程给父进程发运行信号
                
                return 0;
	}
      	else
	{
               
                printf("wait child_fork give signal...\n");
                 
		kill(pid,SIGUSR1);      //给子进程发信号

                while(!parent_run )       //阻塞等待子进程发信号
                {
                      sleep(1);
                }

                printf("parent_fork start\n");
                
               
                waitpid(&child_statu);//父进程等待子进程退出,避免僵死进程
	}

	return 0;
}

运行结果:
在这里插入图片描述

4,代码分析

4.1kill函数原型

在上面的代码中使用到了该函数来进行发送信号(此程序实际上是使用 kill 函数来发送信号。也常用此命令终止一个失控的后台进程。)

#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);

pid:进程ID (process id)
sig:要发送的信号

4.2pid参数分析

pid: 取值有 4 种情况:

pid > 0: 将信号传送给进程 ID 为pid的进程。

pid = 0: 将信号传送给当前进程所在进程组中的所有进程。

pid = -1: 将信号传送给系统内所有的进程。

pid < -1: 将信号传给指定进程组的所有进程。这个进程组号等于 pid 的绝对值。

signum: 信号的编号,这里可以填数字编号,也可以填信号的宏定义,可以通过命令kill -l (“l” 为字母)进行相应查看。

返回值 : 成功返回 0; 错误返回 1

5,其他

5,1 查看进程

ps:查看进程状态 (一个瞬间的进程状态,静态)
top:“实时查看” ,按q退出 (实时动态显示)
pstree 树状查看 (可以看出所属子进程)

5.2、对某个进程发送信号

kill -s 指定发送一个信号 进程的pid
killall:指定一个应用程序名字去发送信号
kill -l 查看系统有什么信号
终端上按“Ctrl+c”组合键通常产生中断信号 SIGINT,终端上按“Ctrl+\”键通常产生中断信号 SIGQUIT,终端上按“Ctrl+z”键通常产生中断信号 SIGSTOP 等。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值