本期主题:
信号
往期地址:
- UNIX环境编程——文件IO
- UNIX环境编程——标准IO
- UNIX环境编程——进程环境与进程控制
- unix高级环境编程——线程详解
- unix环境高级编程——UNIX体系架构
文章目录
- 1.信号概念
- 2.信号操作
- 1.发送信号
- 1.进程组
- 2. 用/bin/kill 程序发送信号
- 3.键盘发送信号
- 2.接收信号
- 1.函数signal
1.信号概念
信号是UNIX和Linux系统响应某些条件而产生的一个事件,用来通知进程系统中发生了某种类型的事件。
用术语生成(raise)表示一个信号的产生,使用术语捕获(catch)表示接收到一个信号。
有很多条件都可以产生信号,这里简单列举几种:
更详细的可看内核代码signal.h中的定义:
传送一个信号到目的进程由两个步骤组成:
1.发送信号内核通过更新目的进程的上下文状态,发送一个信号给目的进程,发送信号可以有以下两个原因:
- 内核检测到一个系统事件,例如除0错误或者子进程终止
- 有进程调用了kill函数,显式的要求内核发送信号给目的进程
每个进程都属于一个进程组,进程组是由一个正整数进程组ID来表示的,unix系统提供了大量向进程发送信号的机制,这些机制都基于进程组概念,可用下面的API来返回进程组ID:
#include2. 用/bin/kill 程序发送信号pid_t getpgrp(void);
/bin/kill 可以向另外的进程发送任意信号,例如
linux> /bin/kill -9 15213 代表发送信号9(SIGKILL)给进程15213 linux> /bin/kill -9 -15213 代表发送信号9给进程组 152133.键盘发送信号
unix shell的作业(job)代表对一条命令行求值而创建的过程,任何时刻至多只有一个前台作业和0个或多个后台作业。
linux> ls | sort 利用管道,在shell界面显示的是一个前台作业,ls和sort命令对应着两个后台作业
在键盘上输入 “CTRL+C"会导致内核发送一个SIGINT信号到前台进程组的每个进程中,终止前台作业。
输入"CTRL+Z” 会挂起前台作业。
接收信号就是通过API对接收到的信号进行处理,执行对应的动作
1.函数signal函数原型:
NAME
signal - ANSI C signal handling
SYNOPSIS
#include
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
例子,自定义两个用户信号,进程在收到用户信号时有对应的打印:
#include#include #include #include void sig_usr(int signo) { if (signo == SIGUSR1) //用户定义信号 printf("receive sigusr1, signo is %drn", signo); else if (signo == SIGUSR2) printf("receive sigusr2, signo is %drn", signo); else printf("receive other signo, signo is %drn", signo); } int main(void) { if (signal(SIGUSR1, sig_usr) == SIG_ERR) printf("can't catch sigusr1n"); if (signal(SIGUSR2, sig_usr) == SIG_ERR) printf("can't catch sigusr2n"); pause(); }



