我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Ruby信号处理详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Ruby信号处理详解

Ruby使用Process.kill发送信号

Process.kill(signal, pid, ...) → integer

Process.kill发送指定的信号给一个或多个进程或进程组:

  • 如果目标pid>0,表示发送信号给指定PID的进程
  • 如果目标pid=0,表示发送信号给调用kill的进程所在进程组的所有进程
  • 如果目标pid<0,表示按照操作系统的规则发送信号。对于Linux来说:
    • 如果pid=-1,表示发送信号给除pid=1的init进程外的所有进程,当然,没有权限的进程将不受影响
    • 如果pid<-1,表示发送信号给-pid所在进程组的所有进程,例如-3000表示发送信号给pid=3000的进程所在进程组的所有进程

Process.kill的第一个参数是要发送的信号:

  • 信号可以是字符串格式的信号名或数值格式的信号ID,INT或SIGINT或1都是有效的信号
  • 如果信号带有负号(如-2-INT),表示发送信号给进程所在进程组而非指定的进程(Linux不支持带负号的信号)
  • 如果信号为0,表示探测是否能发送信号给目标进程,可探测是否能管理目标进程或者探测目标进程是否存活
pid = fork do
  sleep 300
end
# ...
Process.kill("HUP", pid)
Process.wait

Ruby使用trap()设置信号处理程序

Ruby中使用Kernel.trapSignal.trap捕获信号并设置信号处理程序,这两个trap等价。

可设置多个trap来监控多个信号。

Signal.trap(0, proc { puts "Terminating: #{$$}" })
Signal.trap("CLD")  { puts "Child died" }
fork && Process.wait
=begin
Terminating: 27461
Child died
Terminating: 27460
=end

trap的第一个参数是监控的信号名称,可以是字符串的信号名称(如SIGINT),可以是省略SIG前缀的信号名称(如INT),可以是信号对应的数值(如2)。

Ruby支持一个特殊的信号0(对应的字符串信号名为EXIT或SIGEXIT),表示进程退出时会触发的信号。

trap的第二个参数或语句块是捕获到信号后执行的代码。第二个参数有几种特殊情况:

  • 如果第二个参数为字符串IGNORESIG_IGN,表示忽略本次捕获的信号
  • 如果第二个参数为字符串DEFAULTSIG_DFL,表示按照Ruby的默认处理规则来处理
  • 如果第二个参数为字符串EXIT,表示以退出状态码0退出当前进程
  • 如果第二个参数为字符串SYSTEM_DEFAULT,表示按照系统的默认信号处理规则来处理,即以退出状态码141退出进程

避免信号覆盖

使用第三方包的时候,有时候不知道这个包是否定义了某个信号的信号处理程序,或者知道它定义了某信号信号处理程序,但自己定义这个信号的信号处理程序时,不想覆盖第三方包中所定义的处理程序。

这时,应该利用好trap的返回值。每一次trap设置信号处理程序时,都返回本信号之前已经定义的信号处理程序(是一个Proc对象)。只是需要注意,有些信号的初始处理程序是一个字符串值DEFAULT而不是一个Proc对象,因此,应该进行类型判断:

# 第一次定义INT的信号处理程序
first_trap = trap('INT') { 
  first_trap.call if first_trap.is_a? Proc
  puts "first_trap" 
}

# 第二次定义INT的信号处理程序
old_trap = trap('INT') { 
  old_trap.call if old_trap.is_a? Proc   # 调用第一次定义的信号处理程序
  puts "old trap"  # 本次trap时执行的逻辑
}
# 定义好之后,old_trap为第一次定义的信号处理程序

# 之后按下CTRL+C触发INT信号的信号处理程序

多线程信号注册问题

如果是在多线程中注册信号处理程序,该信号处理程序将总是注册在所在进程的main线程中(即使是在其它线程中设置trap())。

pid = fork do
  puts "main Thread: #{Thread.current}"
  Thread.new {
    puts "new Thread: #{Thread.current}"
    trap("TERM", proc { puts "Signal: #{Thread.current}" })
    sleep 2
  }
  sleep 2
end

sleep 1
Process.kill 'SIGTERM', pid
=begin
main Thread: #<Thread:0x00007fffd6ed4c10 run>
new Thread: #<Thread:0x00007fffd714f2b0@a.rb:4 run>
Signal: #<Thread:0x00007fffd6ed4c10 run>
=end

子进程继承信号处理程序

子进程会从父进程继承信号处理程序。

trap 'TERM', proc { puts "Signal: #{Process.pid}" }
puts "Parent: #{Process.pid}"

pid = fork do
  sleep 30
end

puts "Child: #{pid}"
Process.kill 'TERM', pid
=begin
Parent: 2872
Child: 2901
Signal: 2901
=end

更多关于Ruby信号处理的知识请查看下面的相关链接

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Ruby信号处理详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Ruby信号处理的方法

这篇文章主要介绍“Ruby信号处理的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Ruby信号处理的方法”文章能帮助大家解决问题。Ruby使用Process.kill发送信号Process.ki
2023-06-30

linux信号解释(3)--信号处理机制

如果需要进程捕获某个信号,并作出相应的处理,就需要注册信号处理函数(其实就是内核里需要识别信号函数,类似C语言里的include某函数库)。    处理信号就类似软中断,内核为每个进程准备了一段信号向量表,记录信号的处理机制。当某个信号发生
2023-01-31

「信号机制」Python信号处理—sig

转载请注明出处:https://blog.csdn.net/jinixin/article/details/80383177 本文是信号机制三篇记录中的第二篇,介绍Python语言中负责信号处理的signal模块,并会给出一些小demo;第
2023-01-31

python语音信号处理详细教程

在深度学习中,语音的输入都是需要处理的,下面这篇文章主要给大家介绍了关于python语音信号处理的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2023-01-04

php如何处理信号

这篇文章将为大家详细讲解有关php如何处理信号,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。我们常用的信号kill sigterm sigkill【kill命令】ctrl+c sigint【键盘发出】
2023-06-21

【linux】进程信号——信号的保存和处理

文章目录 一、阻塞信号1.1 信号的相关概念1.2 在内核中的构成 二、捕捉信号概念2.1 内核态和用户态2.2 信号捕捉流程图 三、信号操作3.1 sigset_t信号集3.2 信号集操作函数3.2.1 更改block表s
2023-08-20

Django的信号机制详解

Django提供一种信号机制。其实就是观察者模式,又叫发布-订阅(Publish/Subscribe) 。当发生一些动作的时候,发出信号,然后监听了这个信号的函数就会执行。 Django内置了一些信号,比如:django.db.models
2022-06-04

python 对信号 处理的 测试

python 对信号 处理的测试小结下:每次信号 会将当前执行的函数挂起,进入 信号处理函数如果信号处理函数还在处理,又来信号,当前函数仍然被挂起执行完毕回到刚才挂起点继续执行从下面输出 我们就可以看出来 ^Cget an signa
2023-01-31
2023-06-05

golang进程信号怎么处理

在Go语言中,可以使用`os/signal`包来处理进程信号。下面是一个处理 `SIGINT` 和 `SIGTERM` 信号的示例代码:package mainimport ("fmt""os""os/signal""syscall")
2023-10-26

PHP进程信号如何处理

这篇文章主要介绍“PHP进程信号如何处理”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“PHP进程信号如何处理”文章能帮助大家解决问题。一、在Linux操作系统中有哪些信号1、简单介绍信号信号是事件发
2023-07-05

Android Init进程对信号的处理流程详细介绍

Android Init进程对信号的处理流程 在Android中,当一个进程退出(exit())时,会向它的父进程发送一个SIGCHLD信号。父进程收到该信号后,会释放分配给该子进程的系统资源;并且父进程需要调用wait()或waitpi
2022-06-06

Ruby怎么解析处理YAML和json格式数据

今天小编给大家分享一下Ruby怎么解析处理YAML和json格式数据的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Ruby处
2023-06-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录