linux信号

信号

信号是在操作系统中用于通知进程发生了某个特定事件的一种机制。它可以用于进程间通信、处理异常情况以及实现进程间同步等功能。

信号可以由操作系统、其他进程或者进程自身发送给目标进程。当目标进程接收到信号时,会根据事先设置好的信号处理程序来处理该信号。

xin’hao

常见的一些信号

SIGINT(2):终端中断信号,通常由用户按下Ctrl+C发送给前台进程组。
SIGTERM(15):终止信号,通常由kill命令发送给进程。
SIGKILL(9):强制终止信号,无法被捕获或忽略,立即终止进程。
SIGSTOP(17):停止信号,用于暂停进程的执行。
SIGCONT(18):继续信号,用于恢复之前被停止的进程。

信号安装 or 信号注册函数

1.signal

用于捕捉和处理信号的函数
#include <signal.h>

void (*signal(int signum, void (*handler)(int)))(int);
signum参数指定了要设置的信号
handler参数指定了一个函数指针用于处理该信号

忽略信号

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

int main() {
    // 忽略SIGINT信号
    signal(SIGINT, SIG_IGN);

    // 其他代码

    return 0;
}
在上述代码中,我们调用signal()函数将SIGINT信号的处理方式设置为SIG_IGN,即忽略该信号。

当程序运行时,如果用户按下Ctrl+C发送SIGINT信号,该信号将被忽略,程序不会做任何处理。

需要注意的是,某些信号是无法被忽略的,如SIGKILL和SIGSTOP。另外,使用signal()函数设置信号处理方式为SIG_IGN时,可能会导致一些不可预料的行为,因此在使用时需要谨慎。

采用默认操作

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

int main() {
    // 采用默认操作处理SIGINT信号
    signal(SIGINT, SIG_DFL);

    // 其他代码

    return 0;
}
在上述代码中,我们调用signal()函数将SIGINT信号的处理方式设置为SIG_DFL,即采用默认操作来处理该信号。

当程序运行时,如果用户按下Ctrl+C发送SIGINT信号,操作系统会采用默认操作来处理该信号,通常是终止程序的执行。

需要注意的是,某些信号的默认操作可能会导致程序终止或其他不可预料的行为,因此在使用时需要谨慎。另外,使用signal()函数设置信号处理方式为SIG_DFL时,可能会导致一些不可预料的行为,因此在使用时需要注意兼容性和安全性。

自定义信号处理函数

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

void sigint_handler(int signum) {
    printf("Received SIGINT signal\n");
    // 其他自定义操作
}

int main() {
    // 设置SIGINT信号的自定义处理函数
    signal(SIGINT, sigint_handler);

    // 其他代码

    return 0;
}
上述代码中,我们定义了一个名为sigint_handler的函数作为SIGINT信号的自定义处理函数。在该函数中,我们可以编写自己的处理逻辑。

在main()函数中,我们调用signal()函数将sigint_handler函数与SIGINT信号关联起来,即当接收到SIGINT信号时,会调用sigint_handler函数来处理该信号。

当程序运行时,如果用户按下Ctrl+C发送SIGINT信号,操作系统会调用sigint_handler函数来处理该信号,并输出"Received SIGINT signal"。

需要注意的是,自定义的信号处理函数应该尽量简洁,避免阻塞或长时间运行的操作,以免影响程序的正常执行。另外,使用signal()函数设置信号处理方式时,可能会导致一些不可预料的行为,因此在使用时需要注意兼容性和安全性。

alarm

alarm()也称为闹钟函数,它可以在进程中设置一个定时器。当定时器指定的时间到时,内核就向进程发送SIGALARM信号
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void alarm_handler(int signum) {
    printf("Received SIGALRM signal\n");
    // 其他自定义操作
}

int main() {
    // 设置SIGALRM信号的自定义处理函数
    signal(SIGALRM, alarm_handler);

    // 设置定时器,5秒后发送SIGALRM信号
    alarm(5);

    // 其他代码

    while (1) {
        // 循环等待信号
    }

    return 0;
}
上述代码中,我们定义了一个名为alarm_handler的函数作为SIGALRM信号的自定义处理函数。在该函数中,我们可以编写自己的处理逻辑。

在main()函数中,我们调用signal()函数将alarm_handler函数与SIGALRM信号关联起来,即当接收到SIGALRM信号时,会调用	alarm_handler函数来处理该信号。

然后,我们调用alarm()函数设置一个定时器,5秒后发送SIGALRM信号给当前进程。

在主循环中,我们使用一个无限循环来等待信号的到来,以保证程序不会退出。

当程序运行时,5秒后会收到SIGALRM信号,操作系统会调用alarm_handler函数来处理该信号,并输出"Received SIGALRM signal"。

需要注意的是,alarm函数只能设置一个全局的定时器,如果在设置新的定时器之前之前的定时器还未到期,则会取消之前的定时器。另外,使用signal()函数设置信号处理方式时,可能会导致一些不可预料的行为,因此在使用时需要注意兼容性和安全性。

pause

pause()函数是用于将调用进程挂起直到收到信号为止
所需头文件: include<unistd.h>
函数原型: int pause(void)
函数返回值 : -1并且把error值设置成EINTR

kill

向运行中的进程发送信号,默认发送的信号是终止信号,会请求进程退出。kill可能会引起误解,实际上发送的信号可能与杀死进程无关。
在这里插入图片描述

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

int kill(pid_t pid, int sig);

例子

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

int main() {
    pid_t pid = getpid(); // 获取当前进程的进程ID

    printf("Sending SIGTERM signal to process %d\n", pid);

    // 向当前进程发送SIGTERM信号
    int result = kill(pid, SIGTERM);

    if (result == 0) {
        printf("Signal sent successfully\n");
    } else {
        printf("Failed to send signal\n");
    }

    return 0;
}
上述代码中,我们首先使用getpid()函数获取当前进程的进程ID,并将其存储在pid变量中。

然后,我们使用kill函数向当前进程发送SIGTERM信号。如果kill函数返回0,表示信号发送成功,我们输出"Signal sent successfully";如果	返回-1,表示信号发送失败,我们输出"Failed to send signal"。

需要注意的是,kill函数可以向其他进程发送信号,不仅仅限于向当前进程发送信号。但是,向其他进程发送信号需要有足够的权限。

此外,不同的信号有不同的作用和处理方式,可以根据实际需求选择合适的信号。常用的信号包括SIGTERM、SIGKILL、SIGINT等。具体的信号列表可以通过命令"man 7 signal"来查看。

raise

raise函数允许进程向自己发送信号
raise函数:int raise(int sig)
功能:给当前进程发送指定信号(自己给自己发信号),raise(signo)相当于kill(getpid(),signo)
返回值:成功返回0;失败返回非0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值