专栏首页云端漫步使用信号进制实现进程通信

使用信号进制实现进程通信

进程间通信方式

学习操作系统的原理,我们知道,进程间通信有以下几种方式:

  • 管道(pipe)
  • 信号(signal)
  • 消息队列
  • 共享内存
  • 信号量
  • 套接字(socket)

而在应用系统开发中,我们常用的方式就是消息队列和套接字两种方式。在程序中写了一个死循环,运行时,常使用 ctrl+c来中断进程。突然软件卡死了,我们无法关闭,这时,你知道使用kill -9 pip来结束进程。这些基本的操作常识性操作,背后就使用的“信号量"和应用程序发生通信。

信号

信号(Signal)是Linux, 类Unix和其它POSIX兼容的操作系统中用来进程间通讯的一种方式。一个信号就是一个异步的通知,发送给某个进程,或者同进程的某个线程,告诉它们某个事件发生了。当信号发送到某个进程中时,操作系统会中断该进程的正常流程,并进入相应的信号处理函数执行操作,完成后再回到中断的地方继续执行。如果目标进程先前注册了某个信号的处理程序(signal handler),则此处理程序会被调用,否则缺省的处理程序被调用。这种方式只有事件类型,不能实现进程间数据传递。

发送信号

  • kill系统调用
  • kill命令用户发送信号
  • raise库函数发送信号给当前进程 也可以通过键盘发送特定命令实现发送信号,如 ctrl+c SIGINT ctrl+z SIGTSTP ctrl+\ SIGQUIT ctrl+T SIGINFO

信号处理

程序中可以设置接受信号,编写处理函数对信号进行拦截处理,信号有以下处理动作。其中SIGKILL和SIGSTOP不能被程序所捕捉做拦截处理 在mac电脑下,在命令终端输入 kill-l会列出所有的signal信息

HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2

通过信号实现守护进程退出提示

我们要终止一个服务进程,在终止前,让取它打印让其做个倒计时的功能。那么怎么实现这个小功能呢?这就需要用到信号,通过kill发送终止信号,在程序中编写捕捉函数,在信号被触发时,执行捕捉函数。

package main

import (
    "fmt"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    c := make(chan os.Signal)
    signal.Notify(c, syscall.SIGINT)
    fmt.Println("启动服务")
    sig := <-c
    fmt.Println("收到信号", sig)
    TipMsg()

    sum := 0
    for {
        sum += 1
        time.Sleep(1 * time.Second)
    }
}

func TipMsg() {
    fmt.Printf("5秒后退出程序。。。")
    for i := 5; i > 0; i-- {
        time.Sleep(1 * time.Second)
    }
    fmt.Println("退出程序")
    os.Exit(0)
}

go run server.go启动服务,按下 ctrl+c既可完成测试,也可以使用kill发送信号进行测试。方法

$go build
$./server
//另开一个终端tab
$ps -ef | grep server
$kill 2 pid(服务的进程id)

使用信号量实现配置文件热加载

我们在写程序时,常常将一些可控的参数通过配置文件的方式进行加载。这些参数也经常需要动态的调整,那么修改了配置文件后,就需要重新的加载配置文件,就需要重启服务。借助信号量是不就可以达到配置文件重新加载的目的。基于上边的例子,我们将TipMsg的操作改为配置文件重加载的操作,然后将信号修改为SIGUSR1, 完成修改后,使用kill -USER1 pid即可完成配置的重新加载。具体的实现可以参考这篇文章https://segmentfault.com/a/1190000019436438

参考:https://colobu.com/2015/10/09/Linux-Signals/ https://www.jianshu.com/p/f445bfeea40a

本文分享自微信公众号 - 云端漫记(BB_gzhsh)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Debian 9解决SSH中文乱码

    debian广义的Debian是指一个致力于创建自由操作系统的合作组织及其作品,由于Debian项目众多内核分支中以Linux宏内核为主,而且 Debian开发...

    爱游博客
  • nodejs开发环境配置【1】-nvm的安装详解

    nodejs的版本升级相当快,不同版本之间存在了或多或少的差异,在切换版本的时候,如果不使用版本管理工具的话,需要卸载后再安装新的版本,浪费不必要的时间和精力。...

    挥刀北上
  • Docker实战

    2.容器不是虚拟化:运行在Docker容器中的程序接口和主机的Linux内核直接打交道,可以帮助使用已经内置到操作系统中的容器技术

    硬核项目经理
  • yum 命令讲解

    Yum(全称为 Yellow dogUpdater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于R...

    用户5807183
  • Linux服务器管理面板appnode

    最近有发现一个比较不错的Linux服务器管理面板AppNode,AppNode 是一款针对 Linux 服务器的控制管理软件,通过在云服务器内部安装 AppNo...

    爱游博客
  • iTerm的安装及入门配置

    iTerm的很多其他主题你也可以自己去折腾实现个性化,还有很多其他很强大的功能去探索,有机会下次再谈,就先这样。

    Ewall
  • 阿里开源新一代人机对话模型 ESIM:准确率打破世界纪录,提升至 94.1%!

    近日,阿里 AI 开源了新一代人机对话模型 Enhanced Sequential Inference Model(ESIM)。ESIM 是一种专为自然语言推断...

    AI科技评论
  • 宝塔面板如何设置提高服务器性能

    安装宝塔Linux面板 6.9.x,安装Linux工具箱,安装LNMP或LAMP环境

    爱游博客
  • 论OpenVZ与KVM的区别

    虚拟化技术已经发展了很久,经过了很多次的迭代,虚拟化技术可以将单个物理服务器分解为多个较小的虚拟专用服务器(VPS)。

    爱游博客
  • SELINUX工作原理

    Security-Enhanced Linux (SELinux)由以下两部分组成:

    用户5807183

扫码关注云+社区

领取腾讯云代金券