linux—信号

信号:通知进程产生了某个事件。   

一.   signal:改变信号的响应方式        默认:SIG_IGN 默认:SIG_DFL

自定义方法:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>//fork,wait
#include<signal.h>//signal函数
#include<fcntl.h>//open read
void fun(int sig)//自定义类型是typedef void(*sighandle_t)(int)即类型名改为sighandle_t 返回为void类型,形参为Int类型
{
    printf("sid=%d\n",sig);
}
int main()
{
    signal(SIGINT,fun);//自定义  当运行SIDINT即ctrl+c 时,不进行退出而是进行自己定义的fun函数
    while(1)
    {
        printf("hello pid=%d",getpid());
        sleep(1);
    }
}

忽略信号方法:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>//fork,wait
#include<signal.h>//signal函数
#include<fcntl.h>//open read
void fun(int sig)//自定义类型是typedef void(*sighandle_t)(int)即类型名改为sighandle_t 返回为void类型,形参为Int类型
{
    printf("sid=%d\n",sig);
}
int main()
{
    signal(SIGINT,SIG_IGN);//SIG_IGN表示忽略信号ctrl+c  这一行放在最上边
    //signal(SIGINT,fun);//自定义  当运行SIDINT即ctrl+c 时,不进行退出而是进行自己定义的fun函数
    while(1)
    {
        printf("hello pid=%d",getpid());
        sleep(1);
    }
}

第一次自定义,第二次恢复默认:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>//fork,wait
#include<signal.h>//signal函数
#include<fcntl.h>//open read
void fun(int sig)//自定义类型是typedef void(*sighandle_t)(int)即类型名改为sighandle_t 返回为void类型,形参为Int类型
{
    printf("sid=%d\n",sig);
    signal(sig,SIG_DFL);//sig跟SIGINT是一样的,SIG_DFL表示恢复默认
}
int main()
{
    //signal(SIGINT,SIG_IGN);//SIG_IGN表示忽略信号ctrl+c
    signal(SIGINT,fun);//自定义  当运行SIDINT即ctrl+c 时,不进行退出而是进行自己定义的fun函数
    while(1)
    {
        printf("hello pid=%d",getpid());
        sleep(1);
    }
}

二.  kill:  发送信号        int kill(pid_t pid,int sig):pid为给哪个进程发,那个进程的id号                                                                                                 sig为给这个进程发什么信号

头文件#include<signal.h>  返回值为-1是失败

用户在键盘上输入要结束的id号,输入将要发送的信号的代号:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>//fork,wait
#include<signal.h>//signal函数
#include<fcntl.h>//open read
int main(int argc,char*argv[])
{
    if(argc!=3)
    {
        printf("argc err\n");
        exit(1);
    }
    sscanf(argv[1],"%d",&pid);//sscanf与atoi是一样的都是将char*转变为int类型
    sscanf(argv[2],"%d",&sig);
    //int pid=atoi(argv[1]);//argv在定义中为char*类型,但在kill中要为Int类型,顾用atoi将字符改为字符串
    int sig=atoi(argv[2]);
    if(kill(pid,sig)==-1)
    {
        printf("kill err\n");
        exit(1);
    }
}

注意:改代码在使用时需要与上面的  第一次自定义,第二次恢复默认   一起使用:

三.   解决僵死进程用信号处理不会阻塞住父进程代码如下:

#include<stdio.h>//测试fork进程
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<signal.h>//signal的头文件
void fun(int sig)
{
    printf("sig=%d\n",sig);
    wait(NULL);//不会卡住父进程但也会解决僵死进程
}
int main()
{
    int n=0;
    char *s=NULL;
    signal(SIGCHLD,fun);//SIGCHLD是子进程结束后,会默认给父进程发生该信号
    pid_t pid=fork();
    if(pid==-1)
    {
        exit(1);
    }    
    if(pid==0)
    {
        n=3;
        s="child";
    }   
    else
    {
        n=7;
        s="parent";
    }   
    for(int i=0;i<n;i++)
    {
        printf("s=%s curr_pid=%d ppid=%d n=%d n=%p\n",s,getpid(),getppid(),n,&n);//当前进程的id号,getpid()为获取id号,ppid为其父进程id号
        sleep(1);
    }
    exit(0);
}

四.非法内存访问:SIGSEGV

#include<stdio.h>//测试fork进程
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<signal.h>//signal的头文件
void fun(int sig)
{
    printf("sig=%d\n",sig);
}
int main()
{
    signal(SIGSEGV,fun);//若出现非法访问内存,则响应改为fun
    char arr[]="abcde";//常量不能改变值
    arr[1]='c';//err属于非法访问    
    printf("fun nb");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值