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. java中Integer和int的区别

    亲看这里 例子: public class Test { public static void main(String[] args) { Integer i = new Integer(128); ...

  2. 自实现RPC调用

    服务提供者 服务接口: public interface HelloService { public String sayHello(String name); } 服务实现类: public cla ...

  3. tcp 高性能服务, netty,mqtt

    1. io 线程不要有比较长的服务. 全部异步化. [1] netty 权威指南上只是说业务复杂时派发到业务线程池种. 共用的线程池最好都轻量. 多层线程池后, 下层的可以进行隔离. 这个是 mqtt ...

  4. IOS版本判断

    -(void)getIOSVersion { //#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 50000    //此方法和编译器相关 //quanju.iOS ...

  5. 66. Plus One@python

    Given a non-empty array of digits representing a non-negative integer, plus one to the integer. The ...

  6. day3-python 登录

    import datetime # 1. f = open('users') result = f.read() f.close() user_list = result.split() # user ...

  7. v2ex站长专访 - 100offer专访Livid:不仅仅是V站站长

    转载自: https://www.douban.com/group/topic/121611313/ 前几天上网时偶然发现v2ex站长的blog(https://livid.v2ex.com/),了解 ...

  8. 《Java并发编程实战》读书笔记一 -- 简介

    <Java并发编程实战>读书笔记一 -- 简介 并发的历史 并发的历史,也是人类利用有限的资源去提高生产效率的一个的例子. 设想现在有台计算机,这台计算机具有以下的资源: 单核CPU一个 ...

  9. 【南邮】md5 collision write up

    源码: <?php $md51 = md5('QNKCDZO'); $a = @$_GET['a']; $md52 = @md5($a); if(isset($a)){ if ($a != 'Q ...

  10. 蓝桥--2n皇后问题(递归)--搬运+整理+注释

    N皇后问题: #include <iostream> #include <cmath> using namespace std; int N; ];//用来存放算好的皇后位置. ...