信号量
概念
信号量本质是一种描述资源数量的计数器
接口
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信号,默认处理动作终止当前进程
- typedef void(* sighandler_t)(int); sighandler_t signal(int signum,sighandler_t handler);
信号的保存
核心转储
- 概念 : 可以将一个程序异常的时候 将内存中的全部数据存储到硬盘当中 一般会在当前进程的执行目录中生成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是非空指针 则更改进程信号屏蔽字
- how 指示如何更改 如果oset 与set 都是非空指针 则现将原来的信号 屏蔽字备份到oset里 然后根据set和how参数更改信号屏蔽字 假设当前信号屏蔽字为mask 下表说明how参数的可选值
- 返回值 成功返回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)
重要的是 结构体中的 sa_flags字段 可以有效的进行多线程编程 其作用是使当某个信号被处理时使一些其他的信号被屏蔽 而不能并发处理信号 即操作是原子性的
将进程变为后台的指令 ./执行文件 &