【Linux】进程信号_2


八、进程信号

1. 信号

除了可以使用 kill 命令和键盘来生成信号,我们也可以使用系统调用来生成信号。
在这里插入图片描述
kill函数可以对指定进程发送指定信号。
使用方法:

int main(int argc, char *argv[])
{
    if (argc != 3) 
    {
        cout << "Usage: " << argv[0] << " -signumber pid" << endl;
        return 1;
    }

    int signumber = stoi(argv[1] + 1);
    int pid = stoi(argv[2]);

    // 对pid发送signumber信号
    int n = kill(pid, signumber);
    if (n < 0)
    {
        cerr << "kill error, errno : " << strerror(errno) << endl;
    }

    return 0;
}

在这里插入图片描述
raise可以让进程自己调用指定信号。
使用方法:

int main()
{
    int cnt = 0;
    while (true)
    {
        cout << "cnt: " << cnt++ << endl;
        sleep(1);
        if (cnt == 10)
        {
            cout << "send 9 to caller" << endl;
            // 对自己发送9号信号
            raise(9);
        }
    }

    return 0;
}

在这里插入图片描述
abort函数的作用是给自己发送固定信号(6号信号),终止进程。

软件条件 也能产生信号。我们之前学管道通信的时候,当具有读功能的进程关闭读端时,此时由于写操作将毫无意义,所以软件会产生信号给具有写功能的进程,使其关闭写端。
在这里插入图片描述
alarm函数是一个闹钟,可以经过指定秒后发送 SIGALRM 信号。
使用方法:

int main()
{
    // 设置定时器,1秒后发送SIGALRM信号给自己
    alarm(1);
    int cnt = 0;
    while (true)
    {
        cout << "cnt: " << cnt++ << endl;
    }
    return 0;
}

闹钟只会产生信号一次,可以通过捕获信号的方式再次设定闹钟。返回值是上一次的闹钟还剩下多少时间。alarm(0) 的意义就是取消闹钟。
异常情况也可以产生信号。

int main()
{
    int a = 10;
    a /= 0;
    while (true) sleep(1);

    return 0;
}

这里是除0异常,我们来看看会怎样。
在这里插入图片描述
这里产生的信号是 8号信号 SIGFPE
在这里插入图片描述

野指针异常则会产生11号信号 SIGSEGV


未完待续