草庐IT

signal

zqurgy 2023-03-28 原文
  • 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)时,这个信号是如何发送?

  1. 对于进程内部,这些信号集合如何保存?

    • 信号集合用一个结构体数组保存struct k_sigaction action[_NSIG];;
    • 数组大小为64,多处定义#define _NSIG 64;
    • struct k_sigaction- 》维护struct sigaction-》维护struct sigaction
    struct sighand_struct {
        ...
    	wait_queue_head_t	signalfd_wqh;
    	struct k_sigaction	action[_NSIG];// 数组维护
    };
    struct sigaction {
        ...
        __sighandler_t	_sa_handler;
        void (*_sa_sigaction)(int, struct siginfo *, void *);
    };
    
  2. 调用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[sig-1];//提取出信号集合中该信号对应的位置
     	...
     	*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);
      
  3. 其他进程调用某个命令(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的判断

有关signal的更多相关文章

  1. javascript - 没有过载匹配此调用。类型 'string' 不可分配给类型 'Signals' - 2

    我正在使用typescript来构建微服务并处理信号。直到几天前,该代码都运行良好,但最近它开始抛出错误。找不到该问题的修复方法。处理信号的代码。它只是文件的一部分。src/main.tsenumsignals{SIGHUP=1,SIGINT=2,SIGTERM=15}constshutdown=(signal,value)=>{logger.warn("shutdown!")Db.closeAll()process.exit(value)}Object.values(signals).forEach(signal=>{process.on(signal,()=>{logger.war

  2. javascript - localhost : how to setup XHR-Signaling (connection. openSignalingChannel 未被调用) - 2

    我正在使用RTCMultiConnectionv3.4.4我想在本地主机上运行WebRTC。我选择了XHR-Signaling,因为我希望项目完全离线。我不希望它依赖于互联网,因为一切都在本地主机上(稍后部署在LAN上)我包含了XHRConnection.js并设置了connection.setCustomSocketHandler(XHRConnection)。我还覆盖了connection.openSignalingChannel...但是,当我打开/启动房间时,我的视频会显示,但被disableInputButtons()禁用的按钮仍然保持禁用状态。聊天不工作。我在覆盖conne

  3. go - panic : runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x0 addr=0x8 pc=0x48be5c] goroutine 1 [running]: - 2

    我正在尝试使用链表实现多项式的加法。该程序成功地添加了幂0系数,但在第一次遍历后它出现了困惑。这是我到目前为止编写的代码。在初始化temp1!=nil之后,循环遍历else但当权力不同时不进入if循环并进入panic状态packagemainimport("fmt")typeNodestruct{coefficientintpowerintnext*Node}typeliststruct{head*Nodecountint}funcmain(){list1:=&list{}list1.addVariable(5,2)list1.addVariable(4,1)list1.addVari

  4. linux - 将 os.Signal 转换为字符串以便能够将其打印在文件中 - 2

    我需要将os.signal类型转换为字符串才能将其保存在文件中。err:=ioutil.WriteFile("out",sig,0644)我得到这样的错误:./signals.go:37:cannotusesig(typeos.Signal)astype[]byteinargumenttoioutil.WriteFile 最佳答案 你可以做到err:=ioutil.WriteFile("out",[]byte(sig.String()),0644) 关于linux-将os.Signal转

  5. signals - 有没有办法在向进程发送信号后等待? - 2

    当信号(如os.Interrupt)发送到process时,该过程是否等到完成该过程?或者,我们需要再等一段时间吗? 最佳答案 我想你是在问发送信号是否会等到过程完成?答案是,这取决于平台和您发送的信号类型以及进程对信号的处理方式。一些信号比如Kill无法被捕获,会导致进程终止。除非进程处理它们,否则其他人什么都不做。如果流程不处理它们,还有一些人会做一些事情,但如果它想做一些不同的事情,流程可以处理它。在我进一步了解您的问题之前,这是我能给出的最佳答案。 关于signals-有没有办法

  6. macos - 更新到 macOS beta 4 后,go test -cover 抛出 "fatal error: unexpected signal during runtime execution" - 2

    Gobuild和gotest仍然有效。在更新到macOSbeta之前,我使用测试覆盖工具没有遇到任何问题。“去测试”工作正常;但是,所有覆盖率测试命令都抛出此错误(gotest-coverprofile=coverage.out抛出相同的问题)。如果有人知道如何解决这个问题,我将不胜感激!$gotest-covergobuildgithub.com/hunteramericano/ErrorQuiver:/usr/local/Cellar/go/1.6.3/libexec/pkg/tool/darwin_amd64/cover:signal:fatalerror:unexpecteds

  7. signals - 是否可以以 "defer"方式捕获 Ctrl+C 信号 (SIGINT) 并运行清理功能? - 2

    我想捕获从控制台发送的Ctrl+C(SIGINT)信号并打印出一些部分运行总计。 最佳答案 您可以使用os/signal处理传入信号的包。Ctrl+C是SIGINT,因此您可以使用它来捕获os.Interrupt。c:=make(chanos.Signal,1)signal.Notify(c,os.Interrupt)gofunc(){forsig:=rangec{//sigisa^C,handleit}}()您使程序终止和打印信息的方式完全取决于您。 关于signals-是否可以以"d

  8. windows - 转到异常 "signal arrived during cgo execution" - 2

    在什么情况下Go在调用dll时会出现“signalarrivedduringcgoexecution”之类的panic?要调用的代码是——基于go分发的src中的zsyscall_windows.go中的示例:var(//entrynamesfoundusingdumpbin/exportsdllSweph=syscall.NewLazyDLL("swedll32.dll")_swe_jdut1_to_utc=dllSweph.NewProc("_swe_jdut1_to_utc@36")_swe_julday=dllSweph.NewProc("_swe_julday@24"))fu

  9. c - Windows 上的 Ubuntu 上的 Bash : Signal handler does not work - 2

    我尝试运行一个简单的程序(下面的代码),它应该接收并处理SIGUSR1信号。它在“真正的”Linux上运行良好,但如果我在发送SIGUSR1后在WSL上运行它,它会打印Userdefinedsignal1并终止。据我所知,这意味着SIGUSR1未被程序处理,而是调用了默认处理程序。如何使WSL上的信号处理正常工作?提前致谢!源代码:#include#include#includevoidhandle_signal(intsigno){write(1,"Recievedusersignal\n",22);}intmain(){structsigactionact;act.sa_handl

  10. c++ - 错误 C2062 : type 'void' unexpected in signal declaration in QT - 2

    我是新手,我正在编写一个头文件,在其中声明一个将发出信号的类。所以我用一个构造函数声明我的类,两个int变量,我将它们设为private,然后定义我的signal。这是我的.h文件:#ifndefKEYBOARD_H#defineKEYBOARD_HclassKeyBoard{public:KeyBoard();intkeyboard_update();private:intlevel;intsub_level;signals:voidsend_to_MBU(QStringmessage);};#endif现在在.cpp部分,我只是在构造函数中发出一个信号。这是.cpp部分中的代码:#

随机推荐