深入了解Linux中的siginfo_t结构体

发布时间:2023-05-22

一、siginfo_t结构体简介

siginfo_t是一个结构体,具有非常重要的作用。当发生信号的时候,内核会将有关信号的信息存储在siginfo_t结构体中,然后传递给信号处理程序。siginfo_t结构体通常作为函数参数传递给信号处理程序,以提供关于信号的信息。 siginfo_t结构体位于包含在信号头文件<signal.h>中,并在定义<sys types.h>的基础上。该结构体包含有关信号发生的信息,例如发出信号的进程的PID,特定事件的可能的内部状态等。

二、siginfo_t结构体成员变量

siginfo_t结构体的成员变量分别如下:

  • int si_signo:信号编号,表示信号的类型
  • int si_errno:如果si_code是SIGFPE的话,那么si_errno指示初始设定的浮点异常类型。否则,它就是0
  • int si_code:si_code指出了异步事件的类型,它能够使用SI_KERNEL、SI_USER或从SIGRTMIN到SIGRTMAX之间的一个整数。如果si_code为0,表示内核产生的信号
  • pid_t si_pid:进程的ID,该进程发送了该信号
  • uid_t si_uid:执行进程的真实用户ID(uid)
  • int si_status:与si_code相关的状态值
  • clock_t si_utime:在发送进程中累计的用户模式运行时间
  • clock_t si_stime:在发送进程中累计的内核模式运行时间
  • sigval_t si_value:信号的值
  • int si_int:整数等于si_value
  • void *si_ptr:指针等于si_value
  • int si_overrun:未处理时钟过早触发
  • int si_timerid:计时器ID,产生si_code的计时器的ID
  • int si_int:未知
  • void *si_addr:有关硬件异常的附加地址
  • int si_band:有关IO事件的附加事件码
  • int si_fd:与IO事件相关的文件描述符

三、siginfo_t结构体使用示例

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
static void sig_info_handler(int signum, siginfo_t *siginfo, void *data)
{
    printf("Signal %d received with code %d, pid %d, and uid %d\n",
           signum, siginfo->si_code, siginfo->si_pid, siginfo->si_uid);
    exit(EXIT_SUCCESS);
}
int main()
{
    struct sigaction act;
    act.sa_sigaction = sig_info_handler;
    act.sa_flags = SA_SIGINFO;
    if ((sigaction(SIGINT, &act, NULL) != 0))
    {
        fprintf(stderr, "Failed to install signal handler!\n");
        return 1;
    }
    printf("Waiting for signal...\n");
    pause();
}

四、siginfo_t结构体应用实例

siginfo_t结构体非常有用,可以在进程之间传递信号。例如,当系统管理员需要重启系统时,通常会发送SIGTERM信号给所有进程,让它们退出。系统管理员可以编写一个辅助程序,该程序使用kill()函数和siginfo_t结构体向所有进程发送SIGTERM信号,并记录哪些进程成功退出,哪些没有。 总之,siginfo_t结构体是Linux中非常重要的一个结构体,在信号处理、异常处理等方面有着广泛的应用和产生重要的作用。