信号
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGEMT 8) SIGFPE
9) SIGKILL10) SIGBUS11) SIGSEGV12) SIGSYS
13) SIGPIPE14) SIGALRM15) SIGTERM16) SIGURG
17) SIGSTOP18) SIGTSTP19) SIGCONT20) SIGCHLD
21) SIGTTIN22) SIGTTOU23) SIGIO24) SIGXCPU
25) SIGXFSZ26) SIGVTALRM27) SIGPROF28) SIGWINCH
29) SIGINFO30) SIGUSR131) SIGUSR2
https://man7.org/linux/man-pages/man7/signal.7.html
注意是signal(7),不是signal(2)。也不是linux.die.net提供的Manual。
/* Signals. */ #define SIGHUP 1 /* Hangup (POSIX). */ #define SIGINT 2 /* Interrupt (ANSI). */ #define SIGQUIT 3 /* Quit (POSIX). */ #define SIGILL 4 /* Illegal instruction (ANSI). */ #define SIGTRAP 5 /* Trace trap (POSIX). */ #define SIGABRT 6 /* Abort (ANSI). */ #define SIGIOT 6 /* IOT trap (4.2 BSD). */ #define SIGBUS 7 /* BUS error (4.2 BSD). */ #define SIGFPE 8 /* Floating-point exception (ANSI). */ #define SIGKILL 9 /* Kill, unblockable (POSIX). */ #define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ #define SIGSEGV 11 /* Segmentation violation (ANSI). */ #define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ #define SIGPIPE 13 /* Broken pipe (POSIX). */ #define SIGALRM 14 /* Alarm clock (POSIX). */ #define SIGTERM 15 /* Termination (ANSI). */ #define SIGSTKFLT 16 /* Stack fault. */ #define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ #define SIGCHLD 17 /* Child status has changed (POSIX). */ #define SIGCONT 18 /* Continue (POSIX). */ #define SIGSTOP 19 /* Stop, unblockable (POSIX). */ #define SIGTSTP 20 /* Keyboard stop (POSIX). */ #define SIGTTIN 21 /* Background read from tty (POSIX). */ #define SIGTTOU 22 /* Background write to tty (POSIX). */ #define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ #define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ #define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ #define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ #define SIGPOLL SIGIO /* Pollable event occurred (System V). */ #define SIGIO 29 /* I/O now possible (4.2 BSD). */ #define SIGPWR 30 /* Power failure restart (System V). */ #define SIGSYS 31 /* Bad system call. */ #define SIGUNUSED 31 #define _NSIG 65 /* Biggest signal number + 1 (including real-time signals). */
SIGPOLL
SIGIO
linux下SIGIO和SIGPOLL是同一种信号。要收到SIGIO或SIGPOLL信号,需要调用fcntl函数对相应的fd执行操作,指定F_SETOWN并指定参数为需要收到此信号的进程或进程组id。
这样进程还不能收到SIGIO或SIGPOLL信号,还需要调用fcntl函数对相应的fd执行操作,指定F_SETFL,将fd设置为异步模式,O_ASYNC,这样当此fd产生事件时,将会触发SIGIO或SIGPOLL信号,否则信号将被默默丢弃。
#include <stdio.h> #include <signal.h> #include <fcntl.h> #include <unistd.h> int i; void on_signal_io(int sig) { printf("signal: num=SIGIO(%d), %d\n", sig, i++); } int main() { int oflags; signal(SIGIO, on_signal_io); oflags = fcntl(STDIN_FILENO, F_GETFL); fcntl(STDIN_FILENO, F_SETFL, oflags | O_ASYNC); // O_ASYNC, FASYNC fcntl(STDIN_FILENO, F_SETOWN, getpid()); while (1) { } return 0; }
参考poll和select函数。我们完全可以通过这个信号来自己实现poll和select的事件机制。至于能否实现epoll那样的事件机制,没有去验证,估计不行,毕竟epoll这种机制是由内核实现的。像epoll的事件触发机制,首先边缘触发和水平触发就可能无法实现。
信号处理
sighandler_t
类型定义
typedef void (*sighandler_t)(int);
signal
函数原型
sighandler_t signal(int signum, sighandler_t handler);
signal()的行为因UNIX版本而不同,而且在历史上也因Linux的不同版本而不同。避免其使用:使用sigaction()代替。请参阅下面的可移植性。
sigaction
函数原型
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
信号堆栈上下文
signal stack context,即信号堆栈上下文
typedef struct { void *ss_sp; /* Base address of stack */ int ss_flags; /* Flags */ size_t ss_size; /* Number of bytes in stack */ } stack_t;
sigaltstack
sigaltstack - set and/or get signal stack context
函数原型
int sigaltstack(const stack_t *ss, stack_t *oss);
备用信号堆栈
alternate signal stack, 即备用信号堆栈
用户上下文
user context,即用户上下文
getcontext, setcontext - get or set the user context
getcontext
函数原型
int getcontext(ucontext_t *ucp);
setcontext
函数原型
int setcontext(const ucontext_t *ucp);
signal
#include <stdio.h> #include <stdlib.h> #include <signal.h> void do_exit() { printf("exit.\n"); exit(0); } void on_signal_int(int sig) { printf("signal: num=SIGINT(%d)\n", sig); do_exit(); } void on_signal_term(int sig) { printf("signal: num=SIGTERM(%d)\n", sig); do_exit(); } void on_signal_kill(int sig) { printf("signal: num=SIGKILL(%d)\n", sig); do_exit(); } int main(int argc, char** argv) { // SIGINT signal signal(SIGINT, on_signal_int); signal(SIGTERM, on_signal_term); // The signals SIGKILL and SIGSTOP cannot be caught or ignored. // signal(SIGKILL, on_signal_kill); while (1) { } return 0; }
sigaction
#include <stdio.h> #include <stdlib.h> #include <signal.h> void do_exit() { printf("exit.\n"); exit(0); } void on_signal_int_action(int signal, siginfo_t *info, void *ucontext) { printf("signal: num=SIGINT(%d)\n", signal); do_exit(); } void on_signal_term_action(int signal, siginfo_t *info, void *ucontext) { printf("signal: num=SIGTERM(%d)\n", signal); do_exit(); } void on_signal_kill_action(int signal, siginfo_t *info, void *ucontext) { printf("signal: num=SIGKILL(%d)\n", signal); do_exit(); } int main(int argc, char** argv) { struct sigaction on_signal_int, on_signal_term/*, on_signal_kill*/; on_signal_int.sa_sigaction = on_signal_int_action; on_signal_int.sa_flags = SA_SIGINFO; on_signal_term.sa_sigaction = on_signal_term_action; on_signal_term.sa_flags = SA_SIGINFO; // SIGINT signal sigaction(SIGINT, &on_signal_int, NULL); // SIGTERM signal sigaction(SIGTERM, &on_signal_term, NULL); // The signals SIGKILL and SIGSTOP cannot be caught or ignored. // SIGKILL signal // sigaction(SIGKILL, &on_signal_kill, NULL); while (1) { } return 0; }
向信号处理函数传递参数
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <ucontext.h> void do_exit(int exit_code) { printf("exit.\n"); exit(exit_code); } int ucstoi(stack_t stack) { return *((int *) stack.ss_sp); } void on_signal_int_action(int signal, siginfo_t *info, void *ucontext) { ucontext_t *p = (ucontext_t *) ucontext; int exit = ucstoi(p->uc_stack); printf("signal: num=SIGINT(%d), exit=%d\n", signal, exit); do_exit(exit); } void on_signal_term_action(int signal, siginfo_t *info, void *ucontext) { ucontext_t *p = (ucontext_t *) ucontext; int exit = ucstoi(p->uc_stack); printf("signal: num=SIGTERM(%d), exit=%d\n", signal, exit); do_exit(exit); } void on_signal_kill_action(int signal, siginfo_t *info, void *ucontext) { ucontext_t *p = (ucontext_t *) ucontext; int exit = ucstoi(p->uc_stack); printf("signal: num=SIGKILL(%d), exit=%d\n", signal, exit); do_exit(exit); } int createcontext(int arg) { stack_t stack; ucontext_t ucontext; stack.ss_size = SIGSTKSZ; stack.ss_sp = malloc(stack.ss_size); stack.ss_flags = 0; memcpy(stack.ss_sp, &arg, sizeof(arg)); if (sigaltstack(&stack, NULL) == -1) { printf("sig alt stack err.\n"); return 1; } ucontext.uc_link = NULL; ucontext.uc_stack = stack; if (getcontext(&ucontext) == -1) { printf("get context err.\n"); return 1; } return 0; } int main(int argc, char** argv) { struct sigaction on_signal_int, on_signal_term/*, on_signal_kill*/; on_signal_int.sa_sigaction = on_signal_int_action; on_signal_int.sa_flags = SA_SIGINFO; on_signal_term.sa_sigaction = on_signal_term_action; on_signal_term.sa_flags = SA_SIGINFO; int i = -1; if (argc == 2) { i = atoi(argv[1]); } if (createcontext(i)) { printf("create context err.\n"); return 1; } // SIGINT signal sigaction(SIGINT, &on_signal_int, NULL); // SIGTERM signal sigaction(SIGTERM, &on_signal_term, NULL); // The signals SIGKILL and SIGSTOP cannot be caught or ignored. // SIGKILL signal // sigaction(SIGKILL, &on_signal_kill, NULL); while (1) { } return 0; }
相关推荐
### Linux下C语言编程——信号处理函数 #### 一、信号的基本概念与产生 在Linux系统中,**信号**是一种轻量级的进程间通信机制,用于通知接收进程某个特定事件的发生。它不仅可以由硬件异常(如除零错误)触发,也...
在编写Linux系统编程时,理解并正确处理信号是非常重要的。程序员可以通过signal()、sigaction()等系统调用来注册信号处理器,定义信号发生时的行为,如执行默认操作、忽略信号或调用自定义的处理函数。正确地管理和...
这组资源,"Linux下C语言应用编程(作者-杨铸)配套教学ppt",提供了对Linux环境下C语言编程的深入理解和实践指导。以下是一些核心知识点的详细说明: 1. **Linux下C语言编程环境**: - `11-Linux下C语言编程环境....
源代码文件“linuxc.tgz”是一个压缩包,其中包含了书中各个主题的实例代码。学生可以参考这些代码来加深理解,同时通过实际操作来锻炼编程技能。源代码涵盖了上述所有PPT讲解的主题,如简单的文件操作示例、多进程...
本文将详细介绍Linux环境下C语言编程中的几种进程通信方法,包括POSIX无名信号量、System V信号量、System V消息队列以及System V共享内存。 #### 1. POSIX无名信号量 ##### 理论基础 信号量是一种用于控制多个...
在Linux环境下进行C语言编程时,时间概念是一个重要的部分,涉及到如何获取、处理和测量时间。以下是对这些知识点的详细说明: 1. **时间表示**: 在C语言中,时间通常通过`time_t`类型表示,它是一个整型变量,...
### Linux下C语言编程——线程操作 #### 前言:Linux下线程的创建与基础使用 在Linux环境中,线程作为一种重要的并发机制,为开发者提供了在单个进程中执行多个任务的能力。相较于进程,线程之间的切换成本更低,...
### Linux下C语言编程——信号处理 #### 一、引言 在Linux环境下,C语言是一种非常重要的开发工具,尤其在系统级编程方面。信号处理是C语言编程中不可或缺的一部分,它涉及到进程间的通信机制以及如何让程序能够...
在Linux环境下进行C语言编程是许多开发者和技术爱好者深入操作系统内核、实现系统级程序或高效应用的重要途径。本文将详细探讨“Linux下C语言”这一主题,基于标题和描述提供的信息,我们将涵盖C语言的基本概念、...
5. **信号处理**:信号是Linux系统中进程间通信的一种方式,通过signal、raise、sigaction等函数可以捕获和处理信号,实现特定的行为。 6. **系统调用**:Linux提供了丰富的系统调用,如open、close、read、write等...
### Linux操作系统下C语言编程入门知识点详解 #### 一、目录介绍 本文档旨在为初次接触Linux环境下C语言编程的学习者提供全面的指导。主要内容包括Linux下的C语言基础知识、进程管理、文件操作、时间处理、信号...
### C语言Linux系统编程入门知识点概述 #### 一、Linux下的C语言编程基础 ##### 1. 源程序的编译 - **GCC编译器**: 在Linux环境下,使用GCC(GNU Compiler Collection)作为主要的编译工具。GCC不仅支持C语言,还...
在文件I/O方面,Linux系统编程涉及文件描述符、标准输入/输出流、文件打开和关闭、读写操作以及错误处理。文件系统是另一个重要概念,如挂载、卸载、目录操作和文件权限管理等。此外,还要掌握套接字编程,这是网络...