首页 > 编程学习 > linux c 信号

linux c 信号

发布时间:2022/5/14 19:14:37

信号

  1. linux定义了哪些信号,kill -l 查看当前系统定义的所有信号
  2. linux提供信号接口函数
  3. linux信号4种响应方式(进程终止)

查看信号功能:blog

给进程发送信号

命令

killall -信号名字/信号编号 进程名字
kill -信号名字/信号编号 进程PID

常用信号作用

2 SIGINT 终止信号(同ctrl+c)
9 杀死进程
19 SIGSTOP 停止一个作业控制进程
18 SIGCONT 继续停止的程序

发送信号函数

给进程发送linux下定义的信号

函数

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

int kill(pid_t pid, int sig);

int sigqueue(pid_t pid, int sig, const union sigval value);
union sigval {
               int   sival_int;
               void *sival_ptr;
           };

kill 参数:
pid --》 进程pid
sig -》 发送的信号,名字序号都可以

sigqueue 参数:
pid --》 进程pid
sig --》 发送的信号,名字序号都可以
value --》 发送信号另外携带的自定义数据,注意数据类型

给自己发送信号:

#include <signal.h>

int raise(int sig);

间隔时间给当前进程发送信号 SIGALRM

#include <unistd.h>

unsigned int alarm(unsigned int seconds);

替换信号的响应动作

比如:正常情况下INT信号 --》 停止

函数

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

struct sigaction {
               void     (*sa_handler)(int); //响应函数1,同signal设置的函数,只有信号序号传入,二选一
               void     (*sa_sigaction)(int, siginfo_t *, void *); //响应函数2,,二选一
               sigset_t   sa_mask; //先不管
               int        sa_flags; //标志位,设为0使用函数1,设为SA_SIGINFO使用函数2
               void     (*sa_restorer)(void); 
           };

signal 参数:signum --》 需要捕捉的信号
handler --》 信号替换的动作函数
SIG_IGN 忽略信号
SIG_DFL 默认动作

sigaction 参数:signum --》 需要捕捉的信号,除了SIGKILL 和 SIGSTOP
act --》 替换的动作
定义带参数的替换函数:void (*sa_sigaction)(int, siginfo_t *, void *);
参数: int --》 保存发送过来的信号序号
siginfo_t * --》 保存携带的数据指针,见上面的union sigval
void * --》 没有说明,用不到
oldact --》 备份act用的。一般不用设置成NULL。保存之前的act或当前的act,具体用man查看

使用

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

void fun(int sig)
{
    printf("我收到的信号是%d\n", sig);
    printf("信号的默认动作已改变\n");
}

int main()
{
    signal(SIGINT, fun);
    while(1);
}

阻塞进程

阻塞程序,等待信号,收到信号才执行过去

#include <unistd.h>

int pause(void);

信号的屏蔽

忽略(见上):信号发过来就丢失了

屏蔽(也叫阻塞):把信号挡在进程外面,不响应,信号依然存在。解除后依旧可以继续响应之前发送过来的信号

函数

#include <signal.h>

/* Prototype for the glibc wrapper function */
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

参数:
how --》SIG_BLOCK 设置信号阻塞,阻塞set和oldset
SIG_SETMASK 设置信号阻塞,只阻塞set
SIG_UNBLOCK 解除信号阻塞
set --》 保存想要阻塞的所用信号
sigset_t 是linux专门用来保存阻塞信号的阻塞掩码集
#include <signal.h>
int sigemptyset(sigset_t *set); //清空集合
int sigfillset(sigset_t *set); //把linux62个信号一起添加到里面
int sigaddset(sigset_t *set, int signum); //把signum添加进去
int sigdelset(sigset_t *set, int signum); //把signum从里面删除
int sigismember(const sigset_t *set, int signum); //判断signum在不在里面,在 1,不在 0
oldset --》 备份,一般是NULL

使用

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

int main()
{
    sigset_t myset;
    sigaddset(&myset, SIGINT);
    sigaddset(&myset, SIGQUIT);
    
    sigprocmask(SIG_BLOCK, &myset, NULL);
    
    pause();
}
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000