进程信号——信号的产生

目录

1.键盘

2.命令

3. 软件条件

4.系统调用

5.异常

补充知识:

core VS term


 

关于进程信号,其实我们可以通过三个步骤来理解
1.信号的产生
2.信号的捕捉
3.信号的处理

知识储备:
发送信号的本质是:修改目标进程pcb中的信号位图,讲0变为1。

这里写信号的产生
 

1.键盘

我们有些信号是可以通过键盘的快捷键进行发送的
如ctrl+c就是发送的二号信号,让进程终止

2.命令

如kill-9

这是唯一一个不能被注册信号函数的信号?
那什么是注册函数呢?其实就是将信号处理的方式从默认改成自定义。
介绍一个函数

第一个参数传的是信号编号,比如我们像重定义2号信号,就传2,第二个参数是自定义的函数的函数指针。
举个栗子:我们将二号信号注册一下,对应的键盘快捷键为ctrl+c

void signaled(int i)
{
    cout<<"666"<<endl;
}

char arr[100];
int size=0;



int main()
{
    signal(2,signaled);
    test();
    return 0;
}

这时候我们ctrl+c就会答应666了

!!当然九号信号是不允许注册的!!

3. 软件条件

alarm定时器

传入一个定时的时间,到时间之后会默认关闭进程,返回值是剩余的时间,怎么去理解呢?这其实是第二次过后再使用这个函数才会去得到的返回值,第二次吊用这个函数其实是重新去定一个时间,然后再返回上一次定时器剩余的时间。传0的化就是关闭定时器。
 

int main()
{
    alarm(3);
    sleep(1);
    int tm=alarm(4);
    cout<<tm<<end;
    return 0;
}

剩余时间就为2了,这里其实当第一个定时器结束后就会关闭进程了。
我们那个孤雁到

4.系统调用



直接传发送的信号编号,这个不说了

5.异常

其实异常也是一种发送信号的途径。
我们来搞一个10/0;

int main()
{
    int i=10/0;
    return 0;
}

其实就是信号8
我们来看一个奇怪的现象,如果我们将8号信号进行重定义函数

void signaled(int i)
{
    cout << "666" << endl;
    sleep(1);
}
int main()
{
    signal(8,signaled);
    int i=10/0;
    return 0;
}

他就会死循环打印666这是为什么呢?

当cup执行10/0时,自己会判断被除数不能为0,然后再将状态寄存器上的对应比特位进行标记,然后cup就会告诉操作系统,op发送信号将进程的pcb中对应的信号位图上八号进行标记,再执行信号的函数,应为我们重新注册了函数,执行完了函数并不会退出,当再在cpu执行代码时,由于cpu保存了上下文,所以他的状态寄存器上一直标有1,所以会继续告诉操作系统,从此循环。
所以就会导致死循环。

补充知识:

1.上面信号的产生都必须由操作系统来执行,因为
2.信号不是立即处理。
3.信号如果不立即处理,他会保存在进程pcb信号位图中。
4.进程如果收到信号,如果不做处理会执行默认方法,如果进行注册则执行自己设置的方法,当然也可以忽略信号。
5.发信号其实是写信号,会讲进程pcb信号位图上的对应位置改为1。

core VS term

退出进程一般有两种core和term

core是一个文件,用来我们对代码进行调试的,如果以core退出,就是说明代码是有错误的相应的会将错误信息保存到core文件当中。方便我们调试,云服务器默认没有打开这个文件的,
 

ulimit -a就可以查看我们文件是否打开

但是我们进程怎么知道该不该写如信息呢?

其实我们之前就见过,只是没讲而已,我们waitpid就有一个status,来标记是否打开了core文件。

int main()
{
    int id=fork();
    if(id==0)
    {
        int a=10/0;
        exit(1);
    }
    else 
    {
        int statu;
        waitpid(id,&statu,0);
        cout<<"dump core: "<<((statu>>7)&1)<<endl;
    }
    return 0;
}


通过这样的代码就能查看到是否打开dump core,当然是没打开的怎么打开呢?
我们需要去设置一个大小:

ulimit -c 1024 //设置大小


这样就好了再次执行代码

再生成一个core文件,这个文件怎么用呢?其实是调试的时候用。

我们再gdb中core-file就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值