> 文章列表 > Linux0.11 信号(十二)

Linux0.11 信号(十二)

Linux0.11 信号(十二)

Linux0.11 信号(十二)

系列文章目录

Linux 0.11启动过程分析(一)
Linux 0.11 fork 函数(二)
Linux0.11 缺页处理(三)
Linux0.11 根文件系统挂载(四)
Linux0.11 文件打开open函数(五)
Linux0.11 execve函数(六)
Linux0.11 80X86知识(七)
Linux0.11 内核体系结构(八)
Linux0.11 系统调用进程创建与执行(九)
Linux0.11 进程切换(十)
Linux0.11 管道(十一)
Linux0.11 信号(十二)


文章目录

  • 系列文章目录
  • 前言
  • 一、实验代码

前言

    信号机制是 Linux 0.11 为进程提供的一套"局部的类中断机制",即在进程执行的过程
中,如果系统发现某个进程接收到了信号,就暂时打断进程的执行,转而去执行该进程的信
号处理程序,处理完毕后,再从进程"被打断"之处继续执行。


一、实验代码

    这里采用一个关于"信号的发送、接收以及处理"的实例来介绍对系统以及进程处理信号的过程。其包含两个用户进程。一个进程用来接收及处理信号,名字叫做 processsig。它所对应的程序源代码如下 :

// processsing.cpp#include <signal.h>
#include <stdio.h>void sig_usr(int signo) { // 处理信号的函数if (signo == SIGUSR1)printf("received SIGUSR1\\n");elseprintf("received %d\\n", signo);signal(SIGUSR1, sig_usr); // 重新设置 processsing 进程的信号处理函数指针,// 以便下次使用
}int main(int argc, char **argv) {signal(SIGUSR1, sig_usr); // 挂接 processsing 进程的信号处理函数指针for (;;)pause();return 0;
}
// sendsig.cpp#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>int main(int argc, char **argv) {int pid, ret, signo;int i;if (argc != 3) {printf("Usage: sendsig <signo> <pid>\\n");return -1;}signo = atoi(argv[1]);pid = atoi(argv[2]);ret = kill(pid, signo);for (i = 0; i < 1000000; i++) {if (ret != 0)printf("send signal error\\n");}return 0;
}

系统需要具备以下三个功能,以支持信号机制。

  1. 系统要支持进程对信号的发送和接收
        系统在每个进程 task_struct 中都设置了用以接收信号的数据成员 signal(信号位图),每个进程接收到的信号就"按位"存储在这个数据结构中。系统支持两种方式给进程发送信号:
    • 一种方式是一个进程通过调用特定的库函数给另一个进程发送信号;
    • 另一种方式是用户通过键盘输入信息产生键盘中断后,中断服务程程序给进程发送信号。

   这两种方式的信号发送原理是相同的,都是通过设置信号位图(signal)上的信号位来实现的。本实例将结合第一种方式,即一个进程给另一个进程发送信号来展现系统对信号的发送和接收。

  1. 系统要能够及时检测到进程接收到的信号
        系统通过两种方式来检测进程是否接收到信号 :
    • 一种方式是在系统调用返回之前检测当前进程是否接收到信号;
    • 另一种方式是时钟中断产生后,其中断服务程序执行结束之前检测当前进程是否接收到信号。

    这两种信号检测方式大体类似。本实例将结合第一种方式来展现系统对进程接收到的信号的检测。

  1. 系统要支持进程对信号进行处理
        系统要能够保证,当用户进程不需要处理信号时,信号处理函数完全不参与用户进程的执行;当用户进程需要处理信号时,进程的程序将暂时停止执行,转而去执行信号处理函数,待信号处理函数执行完毕后,进程程序将从"暂停的现场处"继续执行。

终端中执行如下命令:

./processsing &./sendsig 10 160	# 10 代表 SIGUSR1 这个信号, # 160 是 processsing 进程的进程号