进程信号 信号量

本文详细介绍了信号量的概念、接口(如semget和semctl)、信号处理机制、信号记录、信号保存(核心转储)以及信号的阻塞和捕捉,同时涵盖了内核态与用户态的区别和相关函数如sighandler_t和signal的使用。
摘要由CSDN通过智能技术生成

信号量

概念

信号量本质是一种描述资源数量的计数器

接口

semget

  • int semget(key_t key,int nsems, int semflg );

  • 头文件
    #include<sys/types.h>
    #include<sys/sem.h>
    #include<sys/ipc.h>

  • 参数

    • key key值 多个线程共同协商好的key值
    • nsems 代表信号量的个数
    • semflg 为IPC_CREAT或IPC_EXCL
      如果只指明CREAT 为存在直接获取或不存在就创建
      如果同事指明 不存在就创建 存在出错返回

    semctl

  • int semctl(int semid, int semnum, int cmd, …)

  • 头文件
    #include<sys/types.h>
    #include<sys/sem.h>
    #include<sys/ipc.h>

  • 参数
    semid 指定信号量的id
    semnum 对指定的信号量集的第几个信号量进行操作
    cmd 操作 常用IPC_RMID 删除

相关命令

ipcs -s 查看所有信号量
ipcrm -s semid 删除该信号量

信号

概念

一种可以被进程/线程识别并做出相应举动的标志 由于随时随地可以接受信号 所以执行流并不会立即执行信号对应的动作

信号记录(普通信号)

  • 短时间内只保存是否产生
  • 所谓的发送信号,本质是写入信号,直接将指定的位图值更改(该操作只能有操作系统进行)

处理信号的方式

  • 默认动作(提前编写好的功能)
  • 忽略
  • 用户自定义动作
  • 接口
    • typedef void(* sighandler_t)(int); sighandler_t signal(int signum,sighandler_t handler);
      • 头文件 #include<signal.h>
      • 参数
        • signum : 收到的是几号信号
        • handler: 用户自己编写的的处理方式
      • 功能 更改对应信号的处理方法 并不会在该函数被调用时调用handler方法
    • unsigned int alarm(unsigned int seconds)
      • 头文件 #include<unistd.h>
      • 返回值:0或者提前被唤醒后剩余的秒数 当被唤醒后再次设置seconds值 seconds会自动加上上次剩余的时间
      • 功能: 设定一个闹钟 告诉内核在seconds秒后给当前进程发送SIGALRM信号,默认处理动作终止当前进程

信号的保存

核心转储

  • 概念 : 可以将一个程序异常的时候 将内存中的全部数据存储到硬盘当中 一般会在当前进程的执行目录中生成core.pid这样的二进制文件,即核心转储文件(云服务器看不到 可以用命令 ulimit -c -size(文件的字节大小 如10 20 1024等) 打开该功能)
    只有action 为Core 的命令会形成核心转储文件
  • 作用: 用于调试 Linux 下 g++ 后加 -g 命令 会将文件编译为调试模式文件 在该模式下出现Core 文件 可以在gdb 下用 core-file core.pid命令直接查看该文件出现的问题在哪 是什么

阻塞信号

  • 进程可以选择阻塞该信号 ,即先不处理该信号 直到时机合适时再处理该信号 也就是说 只有解除信号的阻塞状态 才可以处理该信号

接口

  • int sigprocmask(int how, const sigset_t * set, sigset_t * oset);
    • 头文件 #include<signal.h>
    • 参数
      • how 指示如何更改 如果oset 与set 都是非空指针 则现将原来的信号 屏蔽字备份到oset里 然后根据set和how参数更改信号屏蔽字 假设当前信号屏蔽字为mask 下表说明how参数的可选值
        SIG_BLOCK set 包含了我们希望添加到当前mask的信号 相当于 mask=mask|set
        SIG_UNBLOCK set 包含了我们希望从mask解除的信号 相当于mask=mask&~set
        SIG_SETMASK 设置当前信号屏蔽字为set所指向的值 相当于mask=set
      • set与oset 如果oset是非空指针 读取当前信号屏蔽字通过oset传出 如果set是非空指针 则更改进程信号屏蔽字
    • 返回值 成功返回0 出错返回-1
    • 作用 读取或更改进程的信号屏蔽字(阻塞信号集)
  • sigemptyset(sigset_t*set) 置空对应信号集
  • sigaddset(sigset_t* set, int n) 在对应信号集中添加信号
  • int sigpending <sigmet_t* set>
    • 头文件 #include<signal.h>
    • 功能 检查pending 信号集 将当前的pending位图输出
    • 返回值 成功返回0 失败返回-1

信号的捕捉

信号被立即处理的情况

当一个信号之前被block了 那么block解除之后 他就会被立即处理

内核态与用户态

  • 用户态:执行你写的代码的时候进程所处的状态
  • 内核态:执行OS的代码的时候,进程所处的状态(当进程的时间片结束 需要切换或者调用系统接口)

接口

  • int sigaction(int signum, const struct sigactionact, struct sigaction oldact)
    
act
    重要的是 结构体中的 sa_flags字段 可以有效的进行多线程编程 其作用是使当某个信号被处理时使一些其他的信号被屏蔽 而不能并发处理信号 即操作是原子性的

将进程变为后台的指令 ./执行文件 &

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值