linux系统编程—信号

基本概念

软中断信号(signal,简称为信号)用来通知进程发生了异步事件。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。注意,信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。

收到信号的进程对各种信号有不同的处理方法,处理方法可以分为三类:

捕捉信号:类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处理。

忽略信号:忽略某个信号,对该信号不做任何处理,就象未发生过一样(sigkill和sigstop不能被忽略)。

系统默认动作:对该信号的处理保留系统的默认值,对大部分的信号的缺省操作是使得进程终止。此方法为缺省操作。进程通过系统调用signal来指定进程对某个信号的处理行为。

信号类型

按发出信号的原因分类:
(1)与进程终止相关的信号。当进程退出,或者子进程终止时,发出这类信号。
(2)与进程例外事件相关的信号。如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。
(3)与在系统调用期间遇到不可恢复条件相关的信号。如执行系统调用exec时,原有资源已经释放,而目前系统资源又已经耗尽。
(4)与执行系统调用时遇到非预测错误条件相关的信号。如执行一个并不存在的系统调用。
(5)在用户态下的进程发出的信号。如进程调用系统调用kill向其他进程发送信号。
(6)与终端交互相关的信号。如用户关闭一个终端,或按下break键等情况。
(7)跟踪进程执行的信号。

终端输入kill -l查看信号

31号前为不可靠信号,34号以后为可靠信号。不可靠信号连续发送有可能会造成信号丢失。可靠信号连续发送不会造成信号的丢失。

kill函数

int kill(pid_t pid, int sig);

sig:不推荐直接使用数字,应使用宏名,因为不同操作系统信号编号可能不同,但名称一致。

pid > 0:  发送信号给指定的进程。

pid = 0:  发送信号给与调用kill函数进程属于同一进程组的所有进程。

pid < -1:  发送信号给以-pid为组标识的进程

pid = -1:发送给进程有权限发送的系统中所有进程。

返回值:
成功返回0;失败返回-1

signal函数

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

typedef void (*sighandler_t)(int)为信号的自定义处理函数:参数列表仅有一个int类型,表示接收的信号

参数signum为指定信号(kill -l可查看)

参数handler为要设置的指定信号的处理方式(是系统默认还是忽略还是捕获):

  1. SIG_IGN :忽略

  2. SIG_DFL:系统默认执行方式

  3. 函数指针:用户自定义处理函数

代码实现ctrl+c杀不死进程

#include <stdio.h>
#include <signal.h>//包含头文件


void handler(int signum)
{
    printf("signum = %d\n",signum);//打印信号值
}

int main()
{
    signal(SIGINT,handler);//当收到SIGINI(ctrl+c)信号时 调用handler函数
    while(1);
    return 0;
}

运行结果如下(参数handler改为SIG_IGN也可忽略),每次ctrl+c都会调用handler打印信号值

 代码实现利用kill函数发送信号

signaldemo1.c

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>


void handler(int signum)
{
    printf("signum = %d\n",signum);
    printf("mypid=%d\n",getpid());//让受害者自己输出自己的pid 省事
}

int main()
{
    signal(SIGINT,handler);
    while(1);
    return 0;
}

killdemo.c

#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>


int main(int argc,char **argv)
{
    int pid;
    int signum;
    char cmd[48] = {0};

    signum = atoi(argv[1]);
    pid = atoi(argv[2]);

    printf("pid = %d\n",pid);
    printf("signum = %d\n",signum);

    sprintf(cmd,"kill -%d %d",signum,pid);
    system(cmd);

    //kill(pid,signum);

    return 0;
}

运行结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值