一、进程与信号之信号的概念

 



信号:进程与进程之间通讯机制

  信号是软件中断

  信号是异步事件

  信号来源:内核产生,常用信号kill(),raise(),alarm(),settimer()等

kill -l
 1) SIGHUP     2) SIGINT     3) SIGQUIT     4) SIGILL     5) SIGTRAP
 6) SIGABRT     7) SIGBUS     8) SIGFPE     9) SIGKILL    10) SIGUSR1
11) SIGSEGV    12) SIGUSR2    13) SIGPIPE    14) SIGALRM    15) SIGTERM
16) SIGSTKFLT    17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP
21) SIGTTIN    22) SIGTTOU    23) SIGURG    24) SIGXCPU    25) SIGXFSZ
26) SIGVTALRM    27) SIGPROF    28) SIGWINCH    29) SIGIO    30) SIGPWR
31) SIGSYS    34) SIGRTMIN    35) SIGRTMIN+1    36) SIGRTMIN+2    37) SIGRTMIN+3
38) SIGRTMIN+4    39) SIGRTMIN+5    40) SIGRTMIN+6    41) SIGRTMIN+7    42) SIGRTMIN+8
43) SIGRTMIN+9    44) SIGRTMIN+10    45) SIGRTMIN+11    46) SIGRTMIN+12    47) SIGRTMIN+13
48) SIGRTMIN+14    49) SIGRTMIN+15    50) SIGRTMAX-14    51) SIGRTMAX-13    52) SIGRTMAX-12
53) SIGRTMAX-11    54) SIGRTMAX-10    55) SIGRTMAX-9    56) SIGRTMAX-8    57) SIGRTMAX-7
58) SIGRTMAX-6    59) SIGRTMAX-5    60) SIGRTMAX-4    61) SIGRTMAX-3    62) SIGRTMAX-2
63) SIGRTMAX-1    64) SIGRTMAX    
 查看linux所有 信号共64个 1-31 非实时信号发送信号可能回丢失,不支持信号排队
 32-64实时信号

进程处理信号:

  忽略信号

    SIGKILL和SIGSTOP永远不能被忽略

    忽略硬件异常

    进程启动时SIGUSER1和SIGUSER2两个信号被忽略

  执行默认操作

    每个信号都有默认动作,大部分信号动作是终止信号

 

  捕获信号

    告诉信号内核出现信号是调用自己处理函数

    SIGKILL和SIGSTOP不能被捕获

signal函数

信号注册函数

void (*signal(int signo,void(*func)(int)))(int);

参数
signo 要登记的信号值1-64
func  信号处理函数指针/忽略信号SIG_IGN/默认信号SIG_DEL

若成功返回信号处理函数指针,否则返回SIG_ERR

参数pid
pid > 0 指定进程id发送信号
pid ==0 发送进程同一进程组所有进程
pid <0 指定进程组pid发送信号
pid == -1 发送给进程有权限的所有进程

范列

#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>

void set_signal(int signo)
{
    printf("pid: %d,signo: %d\n",getpid(),signo);
}

int main()
{
    //SIGTSTP就是ctrl + z
    if(signal(SIGTSTP,set_signal) == SIG_ERR)
    {
        printf("set signal error");
    }
    //ctrl+c 
    if(signal(SIGINT,set_signal) == SIG_ERR)
    {
        printf("set signal error");
    }
    int i=0;
    while(i<30)
    {
        printf("i : %d\n",i++);
        sleep(1);
    }
    return 0;
}

  SIGCHLD信号:子进程结束发送此信号给父进程回收资源

#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>

void set_signal(int signo)
{
    printf("%d signal %d\n",getpid(),signo);
    wait(0);
}

void out(int n)
{
    int i=0;
    for (i;i<n;i++)
    {
        printf("%d is %d\n",getpid(),i);
        sleep(2);
    }
}

int main()
{
    
    //注册信号函数
    if(signal(SIGCHLD,set_signal) == SIG_ERR)
    {
        printf("set signal error\n");
        return 1;
    } 
    
    pid_t pid=fork();
    
    if(pid <0)
    {
        printf("fork error\n");
        return 1;
    }
    else if (pid >0)
    {
        //父进程 
        out(20);
    }
    else
    {
        //子进程
        out(10); 
    }
}

 进程间发送信号:

  内核超级用户可以向其他进程发送信号

  一般进程只能向相同uid,gid进程发送信号或者同进程组其他信号

  常用发送信号函数kill(),raise(),alarm(),settimer(),abort()

 

#include <signal.h>

int kill(pid_t pid,int signo)

成功返回0,出错返回-1
向进程发送信号

int raise(int signo)

成功返回0,出错发回-1
向自己发送信号,相当于kill(getpid(),signo)

unsigned int alarm(unsigned int seconds)
返回0或者以前设置定时器的余留秒数,定时器会发送一个SIGALRM 信号

 alarm函数

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void set_signal(int signo)
{
    printf("get signal %d\n",signo);
    alarm(5);
}

int main()
{
    if(signal(SIGALRM,set_signal)==SIG_ERR)
    {
        printf("signal error\n");
        return 1;
    }
    alarm(5);
    int i=0;
    for(i;i<20;i++)
    {
        printf("wait  %d\n",i);
        sleep(2);
    }    
}

 

转载于:https://www.cnblogs.com/peixiguang/p/5844122.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值