linux信号スナップとsigaction関数とsigqueue関数

14792 ワード

linuxシステムのプログラミングを学ぶことについての一定の考え linux API , , linux linux 。
linux , :
  • 高い目標を避けて、必ず着実に、簡単にコードを叩いて、各種のシステム関数
  • を熟知しなければならない.
  • 必ずすべての知識点を食べて、これは私がなぜブログを書く原因です:ブログを書く途中で、実はこの知識点に対する理解を深めました
  • 推荐一位博主的linuxリンク,意外にもおよび大きい!!!良いものは多く分かち合います
  • 次はsigaction関数とsigqueue関数のコード説明です.
  • 関連知識点コードの下の注釈における
  • 私が書くのが理解しにくい場合は、そのブロガーのリンクを参照してください.このブロガーの一番下に添付されています.
  • #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define ERR_EXIT(m) \
        do \
        { \
            perror(m); \
            exit(EXIT_FAILURE); \   
        }while(0)
    
    void myHandler_forsigaction(int signum, siginfo_t *s_t, void *p)
    {
        int myint = 0;
        printf("recv signum: %d 
    "
    , signum); myint = s_t->si_value.sival_int; printf("%d %d
    "
    , myint, s_t->si_int); } int main() { pid_t pid; int ret = 0; struct sigaction act; act.sa_sigaction = myHandler_forsigaction; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; if (sigaction(SIGINT, &act, NULL) < 0) { ERR_EXIT("sigaction error"); } pid = fork(); if (pid == -1) { printf("fork err.....
    "
    ); return 0; } if (pid == 0) { int i = 0; union sigval mysigval; mysigval.sival_int = 222; for (i = 0; i < 10; i++) { ret = sigqueue(getppid(), SIGINT, mysigval); if (ret != 0) { printf("sigqueue err....
    "
    ); exit(0); } else { printf("sigqueue success....
    "
    ); sleep(2); } } } else if (pid > 0) { for(;;) pause(); } return 0; } /**************************************************************************************** 1、sigaction #include int sigaction(int signo, const struct sigaction *act, struct sigaction *oact); sigaction 。 0, -1。 signo 。 act , act 。 oact , oact 。 act oact sigaction : struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); }; void (*sa_handler)(int); ( int ), : act.sa_handler = myHandler; //myHandler igaction(SIGINT, &act, NULL);// signal(SIGINT, myHandler); signal igaction void (*sa_sigaction)(int, siginfo_t *, void *); , , , sigqueue : , sa_flags: act.sa_flags = SA_SIGINFO; : sa_handler , siginfo_t , 。 sa_handler sa_flags 0 :sa_handler sa_sigaction : act.sa_sigaction = myHandler_forsigaction; //myHandler //void myHandler_forsigaction(int signum, siginfo_t *s_t, void *p) // s_t siginfo_t , ( , sigqueue ) siginfo_t siginfo_t { int si_signo; Signal number int si_errno; An errno value int si_code; Signal code int si_trapno; Trap number that caused hardware-generated signal (unused on most architectures) pid_t si_pid; Sending process ID uid_t si_uid; Real user ID of sending process int si_status; Exit value or signal clock_t si_utime; User time consumed clock_t si_stime; System time consumed sigval_t si_value; Signal value // !!! int si_int; POSIX.1b signal // !!! void *si_ptr; POSIX.1b signal int si_overrun; Timer overrun count; POSIX.1b timers int si_timerid; Timer ID; POSIX.1b timers void *si_addr; Memory location which caused fault long si_band; Band event (was int in glibc 2.3.2 and earlier) int si_fd; File descriptor short si_addr_lsb; Least significant bit of address (since kernel 2.6.32) } sigset_t sa_mask; , , , , , 。 , , , sa_mask , 。 int sa_flags; sa_flags , :SA_NODEFER SA_SIGINFO SA_NODEFER ; SA_SIGINFO sa_sigaction , sa_handler sa_flags 0 void (*sa_restorer)(void); 2、 sigqueue int sigqueue(pid_t pid, int sig, const union sigval value); ( kill ), , sigaction() 。 : id, , union sigval, : 0, -1 union sigval : typedef union sigval { int sival_int; void *sival_ptr; }sigval_t; int sival_int; sival_int sigaction sa_sigaction :siginfo_t si_value.sival_int si_int ****************************************************************************************/

    リアルタイム信号と不確実信号の違い
    
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define ERR_EXIT(m) \
        do \
        { \
            perror(m); \
            exit(EXIT_FAILURE); \
        } while(0)
    
    
    void  myhandle(int sig)
    {
        if (sig == SIGINT || sig == SIGRTMIN)
            printf("recv a sig=%d
    "
    , sig); else if (sig == SIGUSR1) { sigset_t s; sigemptyset(&s); sigaddset(&s, SIGINT); sigaddset(&s, SIGRTMIN); sigprocmask(SIG_UNBLOCK, &s, NULL); } } void main() { pid_t pid; struct sigaction act; act.sa_handler = myhandle; act.sa_flags = 0; // if ( sigaction(SIGINT, &act, NULL) <0 ) { ERR_EXIT("sigaction SIGINT"); } if ( sigaction(SIGRTMIN, &act, NULL) <0 ) { ERR_EXIT("sigaction SIGINT"); } if ( sigaction(SIGUSR1, &act, NULL) <0 ) { ERR_EXIT("sigaction SIGINT"); } sigset_t bset; sigemptyset(&bset); sigaddset(&bset, SIGINT); sigaddset(&bset, SIGRTMIN); sigprocmask(SIG_BLOCK, &bset, NULL); pid = fork(); if (pid == -1) { ERR_EXIT("fork err"); } // if (pid == 0) { int i = 0; int ret = 0; union sigval v; v.sival_int = 201; // SIGINT for (i=0; i<3; i++) { ret = sigqueue(getppid(), SIGINT, v); if (ret == -1) { printf("sigqueue SIGINT err, ret: %d, errno:%d
    "
    , ret, errno); exit(0); } else { printf("sigqueue SIGINT success
    "
    ); } } // SIGRTMIN v.sival_int = 301; for (i=0; i<3; i++) { ret = sigqueue(getppid(), SIGRTMIN, v); if (ret == -1) { printf("sigqueue SIGRTMIN err, ret: %d, errno:%d
    "
    , ret, errno); exit(0); } printf("sigqueue SIGRTMIN success
    "
    ); } // SIGUSR1 , kill(getppid(), SIGUSR1); } while(1) { sleep(1); } printf("main....
    "
    ); } /******************************************************************************************* : sigqueue SIGINT success sigqueue SIGINT success sigqueue SIGINT success sigqueue SIGRTMIN success sigqueue SIGRTMIN success sigqueue SIGRTMIN success recv a sig=2 recv a sig=34 recv a sig=34 recv a sig=34 : 1、 ( ) ( ) : 。( , ) 2、 SIGINT SIGRTMIN , SIGUSR1 unblock。 3、 : , pending 0, ( ), block 0, , 。 4、 SIGINT SIGRTMIN 3 , kill SIGUSR1 : ,3 , , 。 *******************************************************************************************/
  • 注意:信号キュー内の信号個数は限られており(一般的には8 k)、この数を超えると古い信号を上書きするのではなく、新しい信号が破棄される.

  • 素晴らしいリンク
    linux信号キャプチャとsigaction関数とsigqueue関数の詳細な説明
  • sigaction関数の分析はとても良くて、ブロガーの同意を得ていませんが、良いものはやはり分かち合いたい
  • です.