Linux教程

linux signal misc

本文主要是介绍linux signal misc,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

linux signal misc 

在user space常使用的signal相关的API

1. 在user space注册信号处理函数

sigaction()函数prototype:

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

    struct sigaction sa_usr;
    sa_usr.sa_flags = 0;
    sa_usr.sa_handler = sig_usr;
    
    sigaction(SIGTERM, &sa_usr, NULL);

 2. sigprocmask

这个系统调用是设置当前线程的task_struct.blocked阻塞signal集合,谁call的这个系统调用,就是设置谁的task_struct.blocked

操作有SIG_BLOCK/SIG_UNBLOCK/SIG_SETMASK,其含义分别为将task_struct.blocked对应bit或上/clear/直接整个赋值为新的block集合

 

在kernel space发送信号给user space进程

send_sig(int sig, struct task_struct *p, int priv)

sig即是signal num,比如SIGTERM,p是进程的task_struct,priv一般情况下传0即可

 

/proc/pid/status关于signal的部分

SigQ: 0/5319
SigPnd: 0000000000000000  
ShdPnd: 0000000000000000
SigBlk: 0000000080000000 #此进程block的signal集合,如果某个bit为1,表示此进程block了此signal;如果为0表示没有block它
SigIgn: 0000000000000000 #此进程ignore的signal集合,如果某一个信号的sa_handler为SIG_IGN,表示此进程ignore此signal,这里打印出来的值为0,表示此进程没有ignore一个signal
SigCgt: 0000000c400084f8 #此进程会捕获的signal集合,如果某个bit为1,表示此进程注册了自己针对这个signal的信号处理函数;如果为0,表示没有注册自己的信号处理函数,即检查某个信号的处理函数sa_handler如果既不是SIG_IGN又不是SIG_DFL,则表示注册了自己的信号处理函数

static inline void task_sig(struct seq_file *m, struct task_struct *p)
{
    unsigned long flags;
    sigset_t pending, shpending, blocked, ignored, caught;
    int num_threads = 0;
    unsigned int qsize = 0;
    unsigned long qlim = 0;

    sigemptyset(&pending);
    sigemptyset(&shpending);
    sigemptyset(&blocked);
    sigemptyset(&ignored);
    sigemptyset(&caught);

    if (lock_task_sighand(p, &flags)) {
        pending = p->pending.signal;
        shpending = p->signal->shared_pending.signal;
        blocked = p->blocked;
        collect_sigign_sigcatch(p, &ignored, &caught);
        num_threads = get_nr_threads(p);
        rcu_read_lock();  /* FIXME: is this correct? */
        qsize = atomic_read(&__task_cred(p)->user->sigpending);
        rcu_read_unlock();
        qlim = task_rlimit(p, RLIMIT_SIGPENDING);
        unlock_task_sighand(p, &flags);
    }

    seq_put_decimal_ull(m, "Threads:\t", num_threads);
    seq_put_decimal_ull(m, "\nSigQ:\t", qsize);
    seq_put_decimal_ull(m, "/", qlim);

    /* render them all */
    render_sigset_t(m, "\nSigPnd:\t", &pending);
    render_sigset_t(m, "ShdPnd:\t", &shpending);
    render_sigset_t(m, "SigBlk:\t", &blocked);
    render_sigset_t(m, "SigIgn:\t", &ignored);
    render_sigset_t(m, "SigCgt:\t", &caught);
}

 

static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
                    sigset_t *catch)
{
    struct k_sigaction *k;
    int i;

    k = p->sighand->action;
    for (i = 1; i <= _NSIG; ++i, ++k) {
        if (k->sa.sa_handler == SIG_IGN)
            sigaddset(ign, i);
        else if (k->sa.sa_handler != SIG_DFL)
            sigaddset(catch, i);
    }
}

 

这篇关于linux signal misc的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!