左脸微笑 发表于 2023-3-26 18:05:03

signal


[*]signal源码位置:、

[*]信号集合../sched/signal.h
[*]信号结构体:../signal_types.h
[*]signal函数:..\kernel\signal.c

sigio的概述流程


[*]对于网络IO来说,一旦收到数据,信号机制会发送sigio这个信号

[*]简单使用sigio,udp可以使用,tcp不行



[*]网卡接收到数据帧,并发送给协议栈
[*]网络协议栈处理原生包(raw package),再发送给应用程序
[*]应用程序进一步处理
signal的工作流程


[*]signal函数和kill函数属于系统调用
[*]从三个方面进行梳理


[*]对于进程内部,这些信号集合如何保存?
[*]调用signal函数时,是怎么保存到进程内部?
[*]其他进程调用某个命令(kill -9 pid)时,这个信号是如何发送?



[*]对于进程内部,这些信号集合如何保存?


[*]信号集合用一个结构体数组保存struct k_sigaction        action;;
[*]数组大小为64,多处定义#define _NSIG                64;
[*]structk_sigaction- 》维护struct sigaction-》维护struct sigaction
struct sighand_struct {
    ...
        wait_queue_head_t        signalfd_wqh;
        struct k_sigaction        action;// 数组维护
};
struct sigaction {
    ...
    __sighandler_t        _sa_handler;
    void (*_sa_sigaction)(int, struct siginfo *, void *);
};
[*]调用signal函数时,是怎么保存到进程内部?


[*]系统调用内部调用关键函数do_sigaction()
[*]将当前进程中信号数组的第X为进行覆盖

[*]X为信号的值#define SIGIO                29-》总共32个信号

int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact{

        struct task_struct *p = current, *t;//当前进程的指针
        struct k_sigaction *k;// 第一问中提过
        ...
        k = &p->sighand->action;//提取出信号集合中该信号对应的位置
        ...
        *k = *act;//该信号的对应位置进行覆盖,如sigio是29,会对索引第28位进行覆盖
        ...
}

[*]额外说明
第一层:`SYSCALL_DEFINE2(signal, int, sig, __sighandler_t, handler)`;

第二层:int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);

[*]其他进程调用某个命令(kill -9 pid)时,这个信号是如何发送?


[*]系统调用内部套层调用关键函数signalfd_notify()
[*]中间套层的函数中会找到kill要发送的pid是否存在,并且找到那个进程
[*]发送信号给该进程,并将其唤醒
static inline void signalfd_notify(struct task_struct *tsk, int sig) {
   
        if (unlikely(waitqueue_active(&tsk->sighand->signalfd_wqh)))
                wake_up(&tsk->sighand->signalfd_wqh);
}
#define wake_up(x)                        __wake_up(x, TASK_NORMAL, 1, NULL)

[*]额外说明
第1层:`SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)`;

第2层:static int kill_something_info(int sig, struct kernel_siginfo *info, pid_t pid);

第3层:static int kill_proc_info(int sig, struct kernel_siginfo *info, pid_t pid);

第4层:int kill_pid_info(int sig, struct kernel_siginfo *info, struct pid *pid);

第5层:int group_send_sig_info(int sig, struct kernel_siginfo *info,
                        struct task_struct *p, enum pid_type type);

第6层:int do_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p,enum pid_type type);

第7层:int send_signal_locked(int sig, struct kernel_siginfo *info,
                     struct task_struct *t, enum pid_type type);

第8层:static int __send_signal_locked(int sig,
struct kernel_siginfo *info,struct task_struct *t, enum pid_type type, bool force);

第9层:static inline void signalfd_notify(struct task_struct *tsk, int sig);

[*]第二层:进行pid的判断



来源:https://www.cnblogs.com/zqurgy/p/17259178.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: signal