zoukankan      html  css  js  c++  java
  • Linux信号函数

    1. signal函数:

    #include <signal.h>
    
    void (*signal(int signo, void (*func)(int)))(int);

    ret-成功返回信号以前的处理配置 出错返回SIG_ERR

    比较容易理解的形式:

    typedef void Sigfunc(int);
    
    Sigfunc *signal(int, Sigfunc *);

    三个宏定义:

    #define SIG_ERR (void(*)())-1 //这里应该是早期写法 函数声明 不检查参数类型 #define SIG_ERR(void(*) (int))-1
    #define SIG_DFL (void(*)())0
    #define SIG_IGN (void(*)())1

    SIG_ERR: 信号注册失败返回SIG_ERR

    SIG_DFL: 采用系统对此信号的默认动作;

    SIG_IGN: 忽略此信号,注意SIGKILL和SIGSTOP不能忽略;

    这三个宏定义不是一定要使用上面的三个值,但是必须是不能声明函数的地址;

    2. 进程启动和创建都信号影响;

    程序启动:当执行一个程序时,所有信号的状态都是系统默认或者忽略。通常所有的信号都被设置成他们的默认动作,除非调用exec的进程忽略该信号。确切的讲,exec函数将原先设置为要捕捉的信号都更改为它们的默认动作,其他信号的状态则不变;(对于一个进程原先要捕捉的信号,当其执行了一个新程序后,自然不能再捕捉它了,因为信号捕捉函数的地址很可能在所执行的新程序文件中已无意义)

    进程创建:当一个进程调用fork时,其子进程继承父进程的信号处理方式。因为子进程在开始时恢复了父进程的存储映像,所以信号捕捉函数的地址在子进程中是有意义的; 

    3. kill和raise函数:

    kill函数将信号发送给进程组。raise函数则允许进程向自身发送信号;

    #include <signal.h>
    
    int kill(pid_t, int signo);
    int raise(int signo);

    raise(signo) == kill(getpid(), signo)

    kill函数pid参数:

    pid>0: 发送信号给进程ID为pid的进程;

    pid==0: 发送信号给与发送进程属于同一进程组的所有进程,而且发送进程具有向这些进程发送信号的权限;

    pid<0: 发送信号给其他进程组ID等于pid的绝对值,而且发送进程具有向这些进程发送信号的权限;

    pid==-1: 发送信号给发送进程有权限向他们发送信号的系统上的所有进程;

    4. alarm和pause函数

    #include <unistd.h>
    
    unsigned int alarm (unsigned int seconds);
    
    ret - 0或者以前设置的闹钟时间的余留秒数

    alarm函数设定一个定时器,经过指定的seconds秒后会产生一个SIGALRM信号;如果不忽略或者不捕捉,其默认动作是终止进程;

    如果第一次设置的没有超时,那么第二次设置的时候alarm返回第一次设置的余留秒数作为返回值,并且旧闹钟被替代;如果本次参数为0,则取消第一次的闹钟,返回余留秒数;

    #include <unistd.h>
    
    int pause(void);
    
    ret- -1, 并将erron设置为EINTR

    pause只有执行了一个信号处理程序并从其返回时,pause才返回,在这种情况下,pause返回-1,并设置errno为EINTR;

    5. 信号集:

    #include <signal.h>
    
    int sigemptyset(sigset_t *set); //初始化由set指向的信号集,清除其中所有信号
    int sigfillset(sigset_t *set); //初始化由set指向的信号集,包含其所有信号
    int sigaddset(sigset_t *set, int signo); //添加信号到信号集
    int sigdelset(sigset_t *set, int signo); //删除信号到信号集
    
    ret-成功返回0 失败返回-1
    
    
    int sigismember(const sigset_t *set, int signo); //某信号是否为信号集成员
    ret-真返回1,假返回0,出错返回-1

    6. sigprocmask函数

    #include <signal.h>
    
    int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);

    首先,若oset!=NULL,那么进程当前的信号屏蔽字通过oset返回;

    其次,若set!=NULL,则参数how指示了如何修改当前信号屏蔽字;

    注意,不能阻塞SIGKILL和SIGSTOP

    how-SIG_BLOCK: 该进程信号屏蔽字是其当前信号屏蔽字和set指向信号集的并集;set包含了我们希望阻塞的附加信号;

           SIG_UNBLOCK: 该进程信号屏蔽字是其当前信号屏蔽字和set指向信号集补集的交集;set包含我们希望解除阻塞的信号;

           SIG_SETMASK: 该进程的信号屏蔽字将被set指向的信号集来替代;

    如果SET==NULL,则how无意义;

    7. sigpending函数:

    #include <signal.h>
    
    int sigpending(sigset_t *set);

    ret-成功返回0 出错返回-1

    函数返回信号集,其中各个信号对于调用进程是阻塞的而不能递送的,因而也一定是当前未决的;

    8. sigaction函数: 

    #include <signal.h>
    
    int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);
    
    ret-成功返回0 出错返回-1

    9. sigsuspend函数:

    #include <signal.h>
    
    int sigsuspend(const sigset_t *sigmask);
    
    ret- -1,并errno设置为EINTR

    函数提供了一个原子操作中先恢复信号屏蔽字,然后使进程休眠;

    将进程的信号屏蔽字的值设置为由sigmask指向的值。在捕捉到一个信号或者发生了一个会终止该进程的信号之前,该进程将被挂起。如果捕捉到一个信号而且从该信号处理程序返回,则sigsuspend返回,并且将该进程的信号屏蔽字设置为调用sigsuspend之前的值;

    10. abort()函数:

    #include <stdlib.h>
    
    void abort(void);

    此函数将SIGABRT信号发送给调用进程。让进程捕捉该信号的意图是,在进程终止前由其执行所需清理操作。

    12. sleep()函数:

    #include <unistd.h>
    
    unsigned int sleep(unsigned int seconds);

    ret-0或者未休眠的秒数

    此函数使调用进程被挂起,直到满足以下条件之一:

    (1) 已经过了seconds所指定的墙上时钟时间;

    (2) 调用进程捕捉到一个信号并从信号处理程序中返回;

    n. 测试代码:

     1 #include <unistd.h>
     2 #include <stdio.h>
     3 #include <signal.h>
     4 
     5 static void sig_user(int signo)
     6 {
     7     if (signo == SIGUSR1){
     8         printf("reveived SIGUSR1
    ");
     9     }
    10     else if (signo == SIGUSR2){
    11         printf("reveived SIGUSR2
    ");
    12     }
    13 }
    14 
    15 int main()
    16 {
    17     if (signal(SIGUSR1, sig_user) == SIG_ERR){
    18         perror("can't catch SIGUSR1
    ");
    19     }
    20 
    21     if (signal(SIGUSR2, sig_user) == SIG_ERR){
    22         perror("can't catch SIGUSR2
    ");
    23     }
    24 
    25     for ( ; ; ){
    26         pause();
    27     }
    28 
    29     return 0;
    30 }
  • 相关阅读:
    从读者角度来看Blog
    NDuiker项目第3天
    IssueVision的List控件源码分析
    测试一个网站的想法
    IssueVision的PaneCaption控件源码分析
    技术研究的时候不要忘了“集成创新”
    人脸识别活体检测之张张嘴和眨眨眼
    jsp>Session 小强斋
    jsp>Request对象 小强斋
    jsp>四种作用域 小强斋
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/5328425.html
Copyright © 2011-2022 走看看