侧边栏壁纸
博主头像
神的孩子都在跳舞博主等级

HARD WORK PAYS OFF

  • 累计撰写 22 篇文章
  • 累计创建 64 个标签
  • 累计收到 0 条评论

进程信号

神的孩子都在跳舞
2024-04-30 / 0 评论 / 0 点赞 / 2,638 阅读 / 3,299 字 / 正在检测是否收录...

在操作系统进程终止操作中,发生异常时,通常我们最多用到的是强制终止,其实系统提供了多个终止的信号,都有不同的用处。最近在写nodejs的测试程序时,因为信号的使用错误,导致出现了无法预测的问题,不得不重新学习这一部分的内容。

信号的定义

Linux系统中有许多信号,每个信号都有不同的用途。以下是常见的信号以及它们的编号和描述:

  1. SIGHUP(1):挂起(Hangup)
  2. SIGINT(2):中断(Interrupt)
  3. SIGQUIT(3):退出(Quit)
  4. SIGILL(4):非法指令(Illegal instruction)
  5. SIGTRAP(5):跟踪/断点(Trace/Breakpoint trap)
  6. SIGABRT(6):中止(Abort)
  7. SIGBUS(7):总线错误(Bus error)
  8. SIGFPE(8):浮点异常(Floating point exception)
  9. SIGKILL(9):杀死(Kill)
  10. SIGUSR1(10):用户定义信号1(User-defined signal 1)
  11. SIGSEGV(11):段错误(Segmentation fault)
  12. SIGUSR2(12):用户定义信号2(User-defined signal 2)
  13. SIGPIPE(13):管道破裂(Broken pipe)
  14. SIGALRM(14):闹钟(Alarm clock)
  15. SIGTERM(15):终止(Termination)
  16. SIGSTKFLT(16):栈故障(Stack fault)
  17. SIGCHLD(17):子进程状态改变(Child status has changed)
  18. SIGCONT(18):继续(Continue)
  19. SIGSTOP(19):停止(Stop)
  20. SIGTSTP(20):终端停止(Keyboard stop)
  21. SIGTTIN(21):后台读取终端(Background read from terminal)
  22. SIGTTOU(22):后台写入终端(Background write to terminal)
  23. SIGURG(23):紧急情况(Urgent condition)
  24. SIGXCPU(24):CPU时间限制(CPU limit exceeded)
  25. SIGXFSZ(25):文件大小限制(File size limit exceeded)
  26. SIGVTALRM(26):虚拟定时器(Virtual alarm)
  27. SIGPROF(27):定时器溢出(Profiling timer expired)
  28. SIGWINCH(28):窗口大小改变(Window size change)
  29. SIGIO(29):异步I/O事件(I/O now possible)
  30. SIGPWR(30):电源故障(Power failure)
  31. SIGSYS(31):非法系统调用(Bad system call)

以上信号是定义在操作系统层级上的,当系统遇到对应的错误时,会根据中断优先级提供不同的终止方式.这些信号是可编程的,也就是说用户可以借着编程语言去向cpu发送任意上述信号来终止某个进程。

# linux 系统下使用kill命令终止进程
kill -15 <pid>
# windows cmd 下
taskkill /F /PID <pid>

通常我们会用-9来kill某一个进程,-9杀死进程的效果是最好的,好比你在做某项工作,收到SIGKILL(9)信号时候,好比发生特别紧急的事情如地震、火情时,立马丢下手头工作立即终止不做任何现场保护。

而使用SIGTERM(15),它是一种请求进程正常终止的信号。当进程接收到SIGTERM信号时,它会进行清理工作并安全地退出。与SIGKILL信号不同,SIGTERM信号可以被进程捕获、处理或忽略。这允许进程在终止之前执行一些清理操作,如关闭文件、释放资源等。

SIGINT(2)它是由终端(通常是用户按下Ctrl+C组合键)发送给前台进程的中断信号。当用户在终端中按下Ctrl+C时,操作系统会发送SIGINT信号给当前正在前台运行的进程。SIGINT信号通常用于中断进程的正常执行,用户通常使用它来终止正在运行的程序。通常,接收到SIGINT信号的进程会进行清理工作,然后优雅地退出。

系统的差异性

在信号的处理上,Windows和Linux有一些不同。以下是一些常见信号以及它们在不同系统中的情况:

信号数字WindowsLinux
SIGHUP1
SIGINT2
SIGQUIT3
SIGILL4
SIGTRAP5
SIGABRT6
SIGBUS7
SIGFPE8
SIGKILL9
SIGUSR110
SIGSEGV11
SIGUSR212
SIGPIPE13
SIGALRM14
SIGTERM15
SIGSTKFLT16
SIGCHLD17
SIGCONT18
SIGSTOP19
SIGTSTP20
SIGTTIN21
SIGTTOU22
SIGURG23
SIGXCPU24
SIGXFSZ25
SIGVTALRM26
SIGPROF27
SIGIO29
SIGPWR30
SIGSYS31
SIGUNUSED0

SIGKILL信号注意问题

由于SIGKILL信号是不做后续操作,强制终止当前进程,当这个进程和某些进程有父子对应关系时,仅仅会关闭当前而不对其父或子进程做处理,有可能会出现意料之外的错误。如果要强制使用SIGKILL的话那还需要做如下的处理。

  • 关闭文件和网络连接: 进程可能打开了文件、套接字或其他资源。在终止之前,需要确保这些资源被正确关闭,以防止资源泄漏或数据丢失。
  • 释放内存: 如果进程分配了内存,需要确保在终止时释放所有已分配的内存,以免造成内存泄漏。
  • 保存数据: 如果进程在终止时需要保存数据,例如正在进行的工作或临时文件,需要确保数据被正确保存,以防止数据丢失。
  • 通知其他进程: 如果进程与其他进程通信或共享资源,可能需要向这些进程发送通知,以便它们能够处理进程终止的情况。
  • 清理临时状态: 进程可能会保持一些临时状态或缓存数据,这些数据在终止时可能需要被清理。
  • 关闭数据库连接或其他外部资源: 如果进程使用了外部资源,如数据库连接或其他服务,需要确保在终止时正确关闭这些连接,以避免资源泄漏或不一致的状态。
  • 执行善后工作: 在一些情况下,进程可能需要执行一些额外的善后工作,例如向日志中记录终止事件或发送通知给管理员。

进程关闭操作

对于有相关进程的情况,我们需要额外操作:

  1. 找到所有相关的进程
  2. 关闭相关进程

找到所有相关的进程

找到进程最方便的方式就是使用系统的进程管理器,如果是在脚本中操作,可以尝试下面操作

  • Unix:

    	# 找到相关的pid,需要下载并安装pstree
    	pstree -p pid <pid>
    

    image.png

    	# 或者根据名字查找, 如node
    	pgrep <name>
    

    image.png

  • Windows:

    	# 使用tasklist + findstr查找对应名字的pid
    	tasklist | findstr "<进程名字>"
    

关闭相关进程

  • Unix:
    	# 把上一步找到的所有进程给关闭
    	kill -9 <pid>
    	# 或者根据名字关闭,使用pkill
    	pkill -9 <name>
    
  • Windows:
    	# windows虽然不支持关闭信号,但可以使用/T支持直接关闭进程树
    	taskkill /T /F /PID <pid>
    	# 根据名字关闭
    	taskkill /T /F /IM <name>
    

关闭端口

如果某些进程开了端口,-9信号还需要通用关闭打开的端口

  • Unix:
    	kill -9 $(lsof -t -i:<端口号>)
    
  • Windows:
    	# 使用netstat 找出要关闭的端口的pid
    	netstat -ano | findstr :"<端口号>"
    	# 关闭端口
    	taskkill /T /F /PID <pid>
    	# 或者使用一条指令完成
    	for /f "tokens=5" %%i in ('netstat -ano ^| findstr :"<端口号>"') do (taskkill /T /F /PID %%i)
    
0
博主关闭了所有页面的评论