C++_10——定时器 & Linux下基于信号的进程间通信

  这一系列文章的目的是在学习了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下 基于信号的进程间通信

进程与线程

  1. 进程是系统进行任务调度和资源分配的最小单位,进程之间可以并发执行。
  2. 线程是程序执行流的最小单元,一个进程可以有多个线程,进程内的线程在其他进程不可见。
  3. 线程切换快于进程切换。
  4. 任务调度:时间片轮转,每个任务执行一个时间片的时间长度,时间片结束后,强制暂停,执行另一个时间片的程序,等到该任务的时间片再次到来。
  5. 进程间资源互不可见,需要通过内核缓冲区进行数据交换,进程A将数据从用户空间放到内核缓冲区,进程B将其从中取走。
  6. 进程间的通信方式主要包括:
    匿名管道
    有名管道
    消息队列
    信号
    信号量
    共享内存
    数据报套接字
    数据流套接字
  7. 线程同步的方式主要包括:基于信号量、互斥量等

基于信号的进程间通信

  1. 信号由某些进程的事件触发/产生,由某些进程捕获处理,可作为一种进程间通信的方式。
  2. 信号的种类
信号名 说明 备注
SIGALRM 超时警告:由alarm函数设置的定时器产生
SIGHUP 连接挂断:由一个处于非连接状态的终端发送给控制进程,或者由控制进程在自身结束时发送给每个前台进程 不懂
SIGKILL 终止进程:因为这个信号不能被捕获或忽略,所以一般在shell中用来强制终止异常进程
SIGINT 终端中断:一般由从终端输入的Ctrl+C组合键 或 预先设置好的中断字符产生
SIGPIPE 如果在向管道写数据时,没有与之对应的读进程,就会产生 TCP客户端向服务端发送消息,客户端关闭后,服务端返回消息时会收到内核发出的SIGPIPE信号
SIGTERM 终止:作为一个请求被发送,要求进程结束运行。UNIX在关机时用该信号要求系统服务停止运行,是kill命令默认发送的信号
SIGUSR1 用户定义:进程之间通信的一个方式,可定义
SIGUSR2 同上
  1. 捕获信号后的自定义处理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. 捕获信号后的自定义处理2——sigaction函数
    与signal函数作用相同,可阻塞指定信号,待处理函数建立后处理(防止,处理函数未建立,而先接收到信号)

    struct sigaction act;
    act.sa_handler = func;
    //创建空的信号屏蔽字,即不屏蔽任何信息
    sigemptyset(&act.sa_mask);
    //使sigaction函数重置为默认行为
    act.sa_flags = SA_RESETHAND;
    
    sigaction(SIGINT, &func, 0);
  3. 触发信号

    // 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可以挂起进程。

  4. 当执行函数触发时,又一个优先级更高的信号到来,当这一高优先级信号处理结束后,前一个函数是否可以再次进入?部分函数可以:
    在这里插入图片描述

参考

  1. https://www.cnblogs.com/qianqiannian/p/7010909.html
  2. 进程间的通信方式——pipe(管道)
  3. https://blog.csdn.net/ljianhui/article/details/10287879

Leave a Reply

Your email address will not be published. Required fields are marked *