这一系列文章的目的是在学习了C++基础后,继续补充一些C++基础和进阶的知识点,包括C++11的相关内容。
以C++11标准为基础。
参考https://blog.csdn.net/ljianhui/article/details/10128731。
Linux下 定时器
这里Linux下定时器 基于Linux下进程间的通信(基于信号的通信)
#include <signal.h>
#include <unistd.h> //alarm的头文件
// 定义定时触发函数
void timer(int sig)
{
if(SIGALRM == sig)
flag1 = 0;
}
// 绑定定时触发函数:改变定时触发信号的默认行为,改为执行timer函数,信号由alarm(int seconds)函数生成
signal(SIGALRM, timer);
// 设置下次触发时间
alarm(10);
Linux下 基于信号的进程间通信
进程与线程
- 进程是系统进行任务调度和资源分配的最小单位,进程之间可以并发执行。
- 线程是程序执行流的最小单元,一个进程可以有多个线程,进程内的线程在其他进程不可见。
- 线程切换快于进程切换。
- 任务调度:时间片轮转,每个任务执行一个时间片的时间长度,时间片结束后,强制暂停,执行另一个时间片的程序,等到该任务的时间片再次到来。
- 进程间资源互不可见,需要通过内核缓冲区进行数据交换,进程A将数据从用户空间放到内核缓冲区,进程B将其从中取走。
- 进程间的通信方式主要包括:
匿名管道
有名管道
消息队列
信号
信号量
共享内存
数据报套接字
数据流套接字 - 线程同步的方式主要包括:基于信号量、互斥量等
基于信号的进程间通信
- 信号由某些进程的事件触发/产生,由某些进程捕获处理,可作为一种进程间通信的方式。
- 信号的种类
信号名 | 说明 | 备注 |
---|---|---|
SIGALRM | 超时警告:由alarm函数设置的定时器产生 | |
SIGHUP | 连接挂断:由一个处于非连接状态的终端发送给控制进程,或者由控制进程在自身结束时发送给每个前台进程 | 不懂 |
SIGKILL | 终止进程:因为这个信号不能被捕获或忽略,所以一般在shell中用来强制终止异常进程 | |
SIGINT | 终端中断:一般由从终端输入的Ctrl+C组合键 或 预先设置好的中断字符产生 | |
SIGPIPE | 如果在向管道写数据时,没有与之对应的读进程,就会产生 | TCP客户端向服务端发送消息,客户端关闭后,服务端返回消息时会收到内核发出的SIGPIPE信号 |
SIGTERM | 终止:作为一个请求被发送,要求进程结束运行。UNIX在关机时用该信号要求系统服务停止运行,是kill命令默认发送的信号 | |
SIGUSR1 | 用户定义:进程之间通信的一个方式,可定义 | |
SIGUSR2 | 同上 |
- 捕获信号后的自定义处理1——signal函数
自定义信号处理方式使用signal函数,输入为信号名和处理函数func。
处理函数func也可以换成特殊值: SIG_IGN(忽略信号)、SIG_DFL(恢复信号的默认行为)。
处理函数func输入是int,无返回值。输入的int是信号名的值,如 SIGALRM == 14。
举个例子就是第一部分的定时器的使用。#include <signal.h> void (*signal(int sig, void (*func)(int)))(int);
-
捕获信号后的自定义处理2——sigaction函数
与signal函数作用相同,可阻塞指定信号,待处理函数建立后处理(防止,处理函数未建立,而先接收到信号)struct sigaction act; act.sa_handler = func; //创建空的信号屏蔽字,即不屏蔽任何信息 sigemptyset(&act.sa_mask); //使sigaction函数重置为默认行为 act.sa_flags = SA_RESETHAND; sigaction(SIGINT, &func, 0);
-
触发信号
// alarm函数 #include <unistd.h> unsigned int alarm(unsigned int seconds); // kill函数:给进程pid,发送信号sig #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig);
函数pause可以挂起进程。
- 当执行函数触发时,又一个优先级更高的信号到来,当这一高优先级信号处理结束后,前一个函数是否可以再次进入?部分函数可以: