linux信号处理、killall、SIGALRM、sigaction函数和结构体、向进程发送信号
向进程发送信号:
killall -14 stats_process_c 2>/dev/null
给统计中间件发送一个闹钟信号 SIGALRM (14) ,统计中间件 stats_process_c 接收到此信号后执行特定函数对统计文件进行处理。
Linux 中 pause() 函数使调用进城挂起直到捕捉到一个信号。只有执行了一个信号处理程序并从其返回时, pause 函数才返回。
程序如下:
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
void stat_process(int sig)
{
printf("receive signature,num is:%d/n",sig);
return;
}
int main()
{
struct sigaction sigact;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigact.sa_flags = sigact.sa_flags | SA_SIGINFO;
sigact.sa_handler = stat_process;
sigaction(SIGALRM,&sigact,NULL);
while(1)
{
pause(); // 进程挂起,直到执行了信号处理程序并从中返回 ,pause 返回。
}
return 0;
}
linux 信号机制之 sigaction 结构体浅析:
信号安装函数 sigaction(int signum,const struct sigaction *act,struct sigaction *oldact) 的第二个参数是一个指向 sigaction 结构的指针(结构体名称与函数名一样,千万别弄混淆了)。在结构 sigaction 的实例中, 指定了对特定信号的处理,信号所传递的信息,信号处理函数执行过程中应屏蔽掉哪些函数等。当然,此指针也可以为 NULL ,进程会以默认方式处理信号。以下 就简单介绍一下 sigaction 结构以及一般的用法。
对于内核头文件而言, struct sigaction 结构体定义在 kernel/include/asm/signal.h, 此头文件又被 kernel/include/linux/signal.h 包含。
对于用户空间的头文件而言, struct sigaction 定义在 /usr/include/bits/sigaction.h, 此头文件又被 /usr/include/signal.h 包含,所以应用程序中如果用到此 结构,只要 #include <signal.h> 即可。注意内核中的定义和应用程序中的定义是不一样的,内核空间的 sigaction 结构只支持函数类型为 __sighandler_t 的信号处理函数,不能处理信号传递的额外信息。具体定义如下:
……
/* Type of a signal handler. */
typedef void (*__sighandler_t)(int);
……
#ifdef __KERNEL__
struct old_sigaction {
__sighandler_t sa_handler;
old_sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
struct sigaction {
__sighandler_t sa_handler;
unsigned long sa_flags;
void (*sa_restorer)(void);
sigset_t sa_mask; /* mask last for extensibility */
};
struct k_sigaction {
struct sigaction sa;
};
#else
/* Here we must cater to libcs that poke about in kernel headers. */
struct sigaction {
union {
__sighandler_t _sa_handler;
void (*_sa_sigaction)(int, struct siginfo *, void *);
} _u;
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
#define sa_handler _u._sa_handler
#define sa_sigaction _u._sa_sigaction
#endif /* __KERNEL__ */
sa_handler 的原型是一个参数为 int ,返回类型为 void 的函数指针。参数即为信号值,所以信号不能传递除信号值之外的任何信息 ;
sa_sigaction 的原型是一个带三个参数,类型分别为 int , struct siginfo * , void *, 返回类型为 void 的函数指针。第一个参数为信号值 ; 第二个参数是一个指向 struct siginfo 结构的指针,此结构中包含信号携带的数据值 ; 第三个参数没有使用。
sa_mask 指定在信号处理程序执行过程中,哪些信号应当被阻塞。默认当前信号本身被阻塞。
sa_flags 包含了许多标志位,比较重要的一个是 SA_SIGINFO ,当设定了该标志位时,表示信号附带的参数可以传递到信号处理函数中。即 使 sa_sigaction 指定信号处理函数,如果不设置 SA_SIGINFO ,信号处理函数同样不能得到信号传递过来的数据,在信号处理函数中对这些信 息的访问都将导致段错误。
sa_restorer 已过时, POSIX 不支持它,不应再使用。
因此,当你的信号需要接收附加信息的时候,你必须给 sa_sigaction 赋信号处理函数指针,同时还要给 sa_flags 赋 SA_SIGINFO , 类似下面的代码:
#include <signal.h>
……
void sig_handler_with_arg(int sig,siginfo_t *sig_info,void *unused){……}
int main(int argc,char **argv)
{
struct sigaction sig_act;
……
sigemptyset(&sig_act.sa_mask);
sig_act.sa_sigaction=sig_handler_with_arg;
sig_act.sa_flags=SA_SIGINFO;
……
}
如果你的应用程序只需要接收信号,而不需要接收额外信息,那你需要的设置的是 sa_handler, 而不是 sa_sigaction, 你的程序可能类似下面的代码:
#include <signal.h>
……
void sig_handler(int sig){……}
int main(int argc,char **argv)
{
struct sigaction sig_act;
……
sigemptyset(&sig_act.sa_mask);
sig_act.sa_handler=sig_handler;
sig_act.sa_flags=0;
……
}
Killall 命令:
[40.7 xu_guo ~]# man killall
KILLALL(1) User Commands KILLALL(1)
NAME
killall - kill processes by name
SYNOPSIS
killall [-Z,--context pattern] [-e,--exact] [-g,--process-group] [-i,--interactive]
[-q,--quiet] [-r,--regexp] [-s,--signal signal] [-u,--user user] [-v,--verbose]
[-w,--wait] [-I,--ignore-case] [-V,--version] [--] name ...
killall -l
killall -V,--version
DESCRIPTION
killall sends a signal to all processes running any of the specified commands. If no
signal name is specified, SIGTERM is sent.
###killall 发送一个信号给所有运行正在运行特定命令的进程。如果没有信号名,则发送 SIGTERM 信号。
Signals can be specified either by name (e.g. -HUP) or by number (e.g. -1) or by
option -s.
### 信号能够通过名字或者号码或者参数 -s 来识别。
If the command name is not regular expression (option -r) and contains a slash (/),
processes executing that particular file will be selected for killing, independent
of their name.
killall returns a zero return code if at least one process has been killed for each
listed command, or no commands were listed and at least one process matched the -u
and -Z search criteria. killall returns non-zero otherwise.
A killall process never kills itself (but may kill other killall processes).
OPTIONS
-e, --exact
Require an exact match for very long names. If a command name is longer than
15 characters, the full name may be unavailable (i.e. it is swapped out). In
this case, killall will kill everything that matches within the first 15
characters. With -e, such entries are skipped. killall prints a message for
each skipped entry if -v is specified in addition to -e,
-I, --ignore-case
Do case insensitive process name match.
-g, --process-group
Kill the process group to which the process belongs. The kill signal is only
sent once per group, even if multiple processes belonging to the same process
group were found.
-i, --interactive
Interactively ask for confirmation before killing.
-l, --list
List all known signal names.
-q, --quiet
Do not complain if no processes were killed.
-r, --regexp
Interpret process name pattern as an extended regular expression.
-s, --signal
Send this signal instead of SIGTERM.
-u, --user
Kill only processes the specified user owns. Command names are optional.
-v, --verbose
Report if the signal was successfully sent.
-V, --version
Display version information.
-w, --wait
Wait for all killed processes to die. killall checks once per second if any
of the killed processes still exist and only returns if none are left. Note
that killall may wait forever if the signal was ignored, had no effect, or if
the process stays in zombie state.
-Z, --context
(SELinux Only) Specify security context: kill only processes having security
context that match with given expended regular expression pattern. Must pre-
cede other arguments on the command line. Command names are optional.
FILES
/proc location of the proc file system
KNOWN BUGS
Killing by file only works for executables that are kept open during execution, i.e.
impure executables can 鈚 be killed this way.
Be warned that typing killall name may not have the desired effect on non-Linux sys-
tems, especially when done by a privileged user.
killall -w doesn 鈚 detect if a process disappears and is replaced by a new process
with the same PID between scans.
If processes change their name, killall may not be able to match them correctly.
AUTHORS
Werner Almesberger <werner@almesberger.net> wrote the original version of psmisc.
Since version 20 Craig Small <csmall@small.dropbear.id.au> can be blamed.
SEE ALSO
kill(1), fuser(1), pgrep(1), pidof(1), pkill(1), ps(1), kill(2).
Linux 2004-11-09 KILLALL(1)
[40.7 xu_guo ~]#
更多推荐
所有评论(0)