1. 信号是软中断,提供处理异步事件的机制

异步事件可以是来源于系统外部(例如用户输入Ctrl-C)也可以来源于系统内(例如除0)
 
内核使用以下三种方法之一来处理信号:
(1) 忽略该信号。SIGKILL和SIGSTOP不能被忽略。
(2) 捕捉并且处理该信号。The kernel will suspend execution of the process’s current code path and jump to a previously registered function.
SIGKILL和SIGSTOP不能被捕捉
(2) 执行默认操作。
 
SIGCHLD:进程终止时,内核向其父进程发送SIGCHLD信号,默认是忽略,如果父进程需要子进程终止信息,而需要显式处理,通常是调用wait函数
SIGINT:用户输入中断字符 Ctrl-C
SIGKILL,SIGSTOP:kill系统调用发出的信号,不能被忽略,不能被捕捉,结果总是终止进程
SIGSEGV:段错误
 

2. 基本的信号管理

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal (int signo, sighandler_t handler);

signal() removes the current action taken on receipt of the signal signo and instead handles the signal with the signal handler specified by handler

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
/* handler for SIGINT and SIGTERM */
static void signal_handler (int signo)
{
if (signo == SIGINT)
printf ("Caught SIGINT!\n");
else if (signo == SIGTERM)
printf ("Caught SIGTERM!\n");
else {
/* this should never happen */
fprintf (stderr, "Unexpected signal!\n");
exit (EXIT_FAILURE);
}
exit (EXIT_SUCCESS);
}
int main (void)
{
/*
* Register signal_handler as our signal handler
* for SIGINT.
*/
if (signal (SIGINT, signal_handler) == SIG_ERR) {
fprintf (stderr, "Cannot handle SIGINT!\n");
exit (EXIT_FAILURE);
}
/*
* Register signal_handler as our signal handler
* for SIGTERM.
*/
if (signal (SIGTERM, signal_handler) == SIG_ERR) {
fprintf (stderr, "Cannot handle SIGTERM!\n");
exit (EXIT_FAILURE);
}
/* Reset SIGPROF's behavior to the default. */
if (signal (SIGPROF, SIG_DFL) == SIG_ERR) {
fprintf (stderr, "Cannot reset SIGPROF!\n");
exit (EXIT_FAILURE);
}
/* Ignore SIGHUP. */
if (signal (SIGHUP, SIG_IGN) == SIG_ERR) {
fprintf (stderr, "Cannot ignore SIGHUP!\n");
exit (EXIT_FAILURE);
}
for (;;)
pause ();
return ;
}
#include <signal.h>
int sigaction (int signo, const struct sigaction *act, struct sigaction *oldact); struct sigaction {
void (*sa_handler)(int); /* signal handler or action */
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask; /* signals to block */
int sa_flags; /* flags */
void (*sa_restorer)(void); /* obsolete and non-POSIX */
};
sigaction() changes the behavior of the signal identified by signo, signo不能为SIGKILL和SIGSTOP
If act is not NULL, the system call changes the current behavior of the signal as specified by act
 
信号行为的继承:
 
 

3. 发送信号

 
int ret;
ret = kill (, SIGHUP);
if (ret)
perror ("kill");
上述代码表示:向pid为1722的进程发送SIGHUP信号
上述代码与以下shell语句等同:
$ kill -HUP 
/*  a simple way for a process to send a signal to itself */
#include <signal.h>
int raise (int signo);
raise (signo);

等同于:

kill (getpid (), signo);

4. 可重入

A reentrant function is a function that is safe to call from within itself (or concurrently, from another thread in the same process).
为了确保可重入,函数不能操作static变量,只能操作 stack-allocated data,并且不能调用 不可重入函数
 

Linux System Programming 学习笔记(十) 信号的更多相关文章

  1. Linux System Programming 学习笔记(二) 文件I/O

    1.每个Linux进程都有一个最大打开文件数,默认情况下,最大值是1024 文件描述符不仅可以引用普通文件,也可以引用套接字socket,目录,管道(everything is a file) 默认情 ...

  2. Linux System Programming 学习笔记(一) 介绍

    1. Linux系统编程的三大基石:系统调用.C语言库.C编译器 系统调用:内核向用户级程序提供服务的唯一接口.在i386中,用户级程序执行软件中断指令 INT n 之后切换至内核空间 用户程序通过寄 ...

  3. Linux System Programming 学习笔记(十一) 时间

    1. 内核提供三种不同的方式来记录时间 Wall time (or real time):actual time and date in the real world Process time:the ...

  4. Linux System Programming 学习笔记(七) 线程

    1. Threading is the creation and management of multiple units of execution within a single process 二 ...

  5. Linux System Programming 学习笔记(六) 进程调度

    1. 进程调度 the process scheduler is the component of a kernel that selects which process to run next. 进 ...

  6. Linux System Programming 学习笔记(五) 进程管理

    1. 进程是unix系统中两个最重要的基础抽象之一(另一个是文件) A process is a running program A thread is the unit of activity in ...

  7. Linux System Programming 学习笔记(四) 高级I/O

    1. Scatter/Gather I/O a single system call  to  read or write data between single data stream and mu ...

  8. Linux System Programming 学习笔记(九) 内存管理

    1. 进程地址空间 Linux中,进程并不是直接操作物理内存地址,而是每个进程关联一个虚拟地址空间 内存页是memory management unit (MMU) 可以管理的最小地址单元 机器的体系 ...

  9. Linux System Programming 学习笔记(八) 文件和目录管理

    1. 文件和元数据 每个文件都是通过inode引用,每个inode索引节点都具有文件系统中唯一的inode number 一个inode索引节点是存储在Linux文件系统的磁盘介质上的物理对象,也是L ...

随机推荐

  1. JQuery EasyUI学习记录(三)

    1.jQuery EasyUI messager使用方式 1.1 alert方法 $(function(){ //1.alert方法---提示框 $.messager.alert("标题&q ...

  2. c++作业:输入两个整数,用函数求两数之和。函数外部声明有什么作用?

    #include <iostream> using namespace std; int main(){ //求两数的和? int a,b,s; cout<<"请你输 ...

  3. iOSAES加密的实现

    +(NSData *)AES256ParmEncryptWithKey:(NSString *)key Encrypttext:(NSData *)text  //加密 { char keyPtr[k ...

  4. VB6 代码编辑页面添加支持滚轮模式

    VB6 中的代码编辑页面默认是不支持滚轮模式的,这让在编辑代码时的体验很是不爽. 但在64位win10系统进行加载配置时,可能会出现问题,可用如下方法解决: http://download.micro ...

  5. VMware12全新安装CentOS-6.9模板机(已优化)

    1.从安装系统开始准备 安装中添加网卡 eth0 ip 10.0.0.210 netmask 24 gateway 10.0.0.254 DNS servers 223.5.5.5 eth1 ip 1 ...

  6. Huawei warns against 'Berlin Wall' in digital world

    From China Daily Huawei technologies criticized recent registration imposed on the Chinese tech comp ...

  7. Python基础-函数参数

    Python基础-函数参数 写在前面 如非特别说明,下文均基于Python3 摘要 本文详细介绍了函数的各种形参类型,包括位置参数,默认参数值,关键字参数,任意参数列表,强制关键字参数:也介绍了调用函 ...

  8. python爬虫集合

    逐渐也写了有二十余篇博文,内容一多就导致有些内容不能够方便快捷定位. 虽然博客有标签进行分类,实际查找时也并不如做一个同类文章的集合来得直观. 这里就对python爬虫相关博文做个集合: 爬虫基础知识 ...

  9. PAT Basic 1074

    1074 宇宙无敌加法器 地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的.而在 PAT 星人开挂的世界里,每个数字的每一位都是不同进制的,这种神奇的数字称为“PAT数”.每个 PAT 星 ...

  10. 12864点阵液晶显示模块的原理和实例程序(HJ12864M-1)

    12864点阵液晶显示模块(LCM)就是由 128*64个液晶显示点组成的一个128列*64行的阵列.每个显示点对应一位二进制数,1表示亮,0表示灭.存储这些点阵信息的RAM称为显示数据存 储器.要显 ...