linux信号处理、killall、SIGALRM、sigaction函数和结构体、向进程发送信号

来源:互联网 发布:项目管理强矩阵 编辑:程序博客网 时间:2024/04/27 23:34

向进程发送信号:

killall -14 stats_process_c 2>/dev/null 

给统计中间件发送一个闹钟信号SIGALRM(14),统计中间件stats_process_c接收到此信号后执行特定函数对统计文件进行处理。

         Linuxpause()函数使调用进城挂起直到捕捉到一个信号。只有执行了一个信号处理程序并从其返回时,pause函数才返回。

 

程序如下:

#include <stdlib.h>

#include <stdio.h>

#include <signal.h>

 

void stat_process(int sig)

{

        printf("receivesignature,num is:%d/n",sig);

        return;

}

 

int main()

{

        struct sigactionsigact;

       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(intsignum,const struct sigaction *act,struct sigaction *oldact)的第二个参数是一个指向sigaction结构的指针(结构体名称与函数名一样,千万别弄混淆了)。在结构sigaction的实例中,指定了对特定信号的处理,信号所传递的信息,信号处理函数执行过程中应屏蔽掉哪些函数等。当然,此指针也可以为NULL,进程会以默认方式处理信号。以下就简单介绍一下sigaction结构以及一般的用法。

        对于内核头文件而言,structsigaction 结构体定义在kernel/include/asm/signal.h,此头文件又被kernel/include/linux/signal.h包含。
       
对于用户空间的头文件而言,structsigaction定义在 /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_tsa_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的原型是一个带三个参数,类型分别为intstruct siginfo *void *,返回类型为void的函数指针。第一个参数为信号值;第二个参数是一个指向struct siginfo结构的指针,此结构中包含信号携带的数据值;第三个参数没有使用。

sa_mask指定在信号处理程序执行过程中,哪些信号应当被阻塞。默认当前信号本身被阻塞。

sa_flags包含了许多标志位,比较重要的一个是SA_SIGINFO,当设定了该标志位时,表示信号附带的参数可以传递到信号处理函数中。即使sa_sigaction指定信号处理函数,如果不设置SA_SIGINFO,信号处理函数同样不能得到信号传递过来的数据,在信号处理函数中对这些信息的访问都将导致段错误。

sa_restorer已过时,POSIX不支持它,不应再使用。

        因此,当你的信号需要接收附加信息的时候,你必须给sa_sigaction赋信号处理函数指针,同时还要给sa_flagsSA_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 specifiedcommands. 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 notregular 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 foreach

      listed command, or no commands were listed and at least one processmatched  the  -u

      and -Z search criteria. killall returns non-zero otherwise.

      A killall process never kills itself (but may kill other killallprocesses).

OPTIONS

      -e, --exact

              Require  an exact match for very long names. If acommand name is longer than

              15 characters, the full name maybe unavailable (i.e. it is swapped out). In

              this  case, killall  will  kill everything that matches within the first 15

              characters. With -e, such entriesare skipped.  killall prints amessage  for

              each skipped entry if -v isspecified in addition to -e,

      -I, --ignore-case

              Do case insensitive process namematch.

      -g, --process-group

              Kill  the process group to which the processbelongs. The kill signal is only

              sent once per group, even ifmultiple processes belonging to the same process

              group were found.

      -i, --interactive

              Interactively ask forconfirmation before killing.

      -l, --list

              List all known signal names.

      -q, --quiet

              Do not complain if no processeswere killed.

      -r, --regexp

              Interpret process name pattern asan extended regular expression.

      -s, --signal

              Send this signal instead ofSIGTERM.

      -u, --user

              Kill only processes the specifieduser owns. Command names are optional.

      -v, --verbose

              Report if the signal wassuccessfully 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 stillexist and only returns if none are left.  Note

              that killall may wait forever ifthe signal was ignored, had no effect, or if

              the process stays in zombiestate.

      -Z, --context

              (SELinux Only) Specify securitycontext: kill only processes having security

              context  that match with given expended regularexpression pattern. Must pre-

              cede other arguments on thecommand line. Command names are optional.

FILES

      /proc     location of the procfile system

KNOWN BUGS

      Killing by file only works for executables that are kept open duringexecution, i.e.

      impure executables can be killed this way.

      Be warned that typing killall name may not have the desired effect onnon-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 themcorrectly.

AUTHORS

      Werner  Almesberger  <werner@almesberger.net>  wrote the original version of psmisc.

      Since version 20 Craig Small <csmall@small.dropbear.id.au> can beblamed.

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 ~]#

原创粉丝点击