20.Linux/Unix 系统编程手册(上) -- 信号:基本概念

1.引发内核为进程产生信号的各类事件
	1.硬件发生异常,即硬件检测到一个错误条件并通知内核,再由内核发送响应信号给相关进程
	2.用户键入了能够产生信号的终端特殊字符
	3.发生了软件事件。如进程执行cpu时间到了,或者该进程的子进程退出了

2.信号分两大类
	1.第一组用于内核向进程通知事件
	2.另一组由实时信号构成

	信号因某些事件而产生。信号产生后,会于稍后被传递给某一进程,而进程也会采取某些措施来响应信号。
  在产生和到达期间,信号处于等待(pending)状态。
  	通常,一旦(内核)接下来要调度该进程运行,等到的信号会马上到达,或者如果进程正在运行,即会立即传递信号(例如,
  进程向自身发送信号)。然后,有时需要确保一段代码不为传递来的信号所中断。为了做到这一点,可以将信号添加到进程的
  信号掩码中---目前会阻塞该组信号到达。如果产生的信号属于阻塞之列,那么信号将保持等待状态,直到稍后对其解除阻塞(
  从信号掩码中移除)。进程可使用各种系统调用对其信号掩码添加和移除信号.

3.进程对信号的处理方式
	1.忽略信号
	2.杀死进程
	3.产生核心转储文件,同时终止进程:核心转储文件包含对进程虚拟内存的镜像
	4.停止进程
	5.于之前暂停后再度恢复进程的执行

	对进程的处置:
	1.采用默认行为
	2.忽略信号
	3.执行信号处理函数

	通知内核应当去调用某一处理程序的行为,通常称之为安装或者建立信号处理程序。调用信号处理程序以响应传递过来的信号,
  则称之为信号已处理,或者已经捕获。
    请注意,无法将信号处置设置为终止进程或者转储核心(除非这是对信号的默认处置)

4./proc/PID/status
	/proc/PID/status 文件中包含各种位掩码字段,通过检查这些掩码可以确定进程对信号的处理。位掩码以十六进制形式显示,
  最低有效位代表信号1,相邻的左边以为代表信号2,以此类推。这些字段分别为 SigPnd(基于线程的等待信号),ShdPnd(进程级等待信号),
  SigBlk(阻塞信号),SigIgn(忽略信号),SigCgt(捕获信号)

5.信号类型和默认行为
	SIGABRT : 进程调用 abort() 函数,会产生核心转储文件。

	SIGALRM : 调用 alarm() 或者 setitimer() 而设置的定时器到期产生的信号

	SIGBUS : 产生该信号即表示发生了某种内存访问错误。

	SIGPIPE : 当某一进程试图向管道,FIFO,或者套接字写入信息时,如果这些设备并无响应的阅读进程,那么将产生该信号。

	SIGQUIT : 当用户键入 control + \ 时,该信号将发往前台进程组。默认终止进程,并产生核心转储文件。如果进程陷入无限循环,或者
  	不再响应,使用 SIGQUIT 信号就和合适。键入 control + \ ,再调用 gdb 调试器加载刚才生成的核心转储文件,接着用 backtrace 命令,
  	来获取跟踪信息,就能发现正在执行的是程序的哪部分代码。

  	SIGTERM : 这是用来终止进程的标准信号,也是 kill 和 kilall 命令所发送的默认信号。用户有时会使用 kill all 或者 kill -9 显示
  	向进程发送 killall 信号。然后,这一做法通常是错误的。精心设计的程序应该为 SIGTERM 信号设置处理程序,以便其能够预先清楚临时文件和
  	释放其他资源,从而全身而退。发送 sigkill 信号可以杀掉某个进程,从而绕过了 SIGTERM 信号的处理函数。因此,总是应该先尝试使用 SIGTERM信号
  	来终止某个进程,而把 SIGKILL 信号作为最后的手段,去对付那些不响应 SIGTERM 信号的失控进程。

  	SIGTRAP : 该信号用来实现断点调试功能以及 strace(1) 命令。

  	SIGTSTP : 这是作业控制的停止信号,当用户键入 control + Z 时,将发送该信号给前台进程组,使其停止运行。

  	SIGTTIN : 在作业控制 shell 下运行时,若后台进程试图对终端进行 read 操作,终端驱动程序发送此信号

  	SIGTTOU : 在作业控制 shell 下运行时,如果对终端启用了 TOSTOP 选项,而某一后台进程组试图对终端进行 write 操作,那么发送此信号

  	SIGURG : 系统发送该信号给一个进程,表示有紧急数据

  	SIGUSR1 : 该信号和 SIGUSR2 信号提供程序员定义使用。内核绝不会为进程产生这些信号,进程可以使用这些信号来互相通知时间的发送,或者
  	彼此同步。

6.检查进程是否存在方法
	1.kill(0) 发送空信号
	2.wait() 系统调用
	3.信号量和排他文件锁
	4.诸如管道和FIFO之类的IPC通道
	5./proc/PID 接口

7.信号掩码
	内核会为每个进程维护一个信号掩码,即一组信号,并将阻塞其针对该进程的传递。
	如果将阻塞的信号发送给某进程,那么对该信号的传递将延后,直至从进程信号掩码中移除该信号,从而接触阻塞为止。

	向信号掩码添加一个信号的方法:
	1.当调用信号处理程序时,可将引发调用的信号自动的添加到信号掩码中。
	2.sigaction() 函数建立信号处理程序时,可以指定一组额外的阻塞信号
	3.使用 sigprocmask() 系统调用,显示的向信号掩码中添加或移除信号

8.处于等待的信号
	如果某进程接受了一个该进程正在阻塞的信号,那么会将该信号添加到进程的等待信号集中。当(且如果)之后解除了对该信号的
  锁定时,会随之将该信号传递给此进程。
	sigpending(); // 获取处于等待状态的信号集


signal();
kill();
raise();
killpg();
strsignal();
psignal();
sigemptyset();  // 初始化一个未包含任何成员的信号集
sigfillset(); // 初始化一个信号集,使其包含所有信号
sigaddset(); //添加一个信号
sigdelset(); //移除一个信号
sigismember(); // 判断信号sig是否是信号集 set 的成员
sigandset();
sigorset();
sigisemptyset();
sigprocmask(); //信号掩码的操作
sigpending(); 
sigaction();
pause();



 

猜你喜欢

转载自blog.csdn.net/enlyhua/article/details/82730565