• 22、linux信号学习(1)


     1、最简单的安装信号

    示例1

    View Code
    #include <iostream>
    using namespace std;
    #include <signal.h>

    void func(int sig)
    {
    cout<<"用户自定义"<<endl;
    }
    int main()
    {
    signal(SIGUSR1,func);
    pid_t pid = getpid();
    kill(pid, SIGUSR1);/*用户自定义信号,kill具有发信号的功能,这行代码向“自身进程pid发信号SIGUSR1,执行的最终结果是触发SIGUSR1信号*/
    }

    2、更高层软件形式的异常,称为unix信号,它允许进程中断其他进程。一个信号(signal)就是一条消息,它通知进程一个某种类型的事件已经在系统中发生了。Linux支持30种不同类型的信号。

    调用kill函数可以向指定进程发出指定的信号,调用raise函数,可以使进程向自己发送指定的信号,alarm可以使进程向自己经过指定的秒数后发送SIGALRM信号。

    wps_clip_image-9923

    SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。

    SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。

    SIGQUIT信号未产生过,一旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler

        sigset_t类型对于每种信号用一个bit表示“有效”或“无效”状态,至于这个类型内部如何存储这些bit则依赖于系统实现。

    3、unix shell 使用作业(job)的抽象概念来表示求值一条命令行而产生的进程。在任何时刻,到多只有一个前台作业和0个或式个后台作业。shell为每个作业创建一个独立的进程组。

    4、函数

    1)alarm

    #include<unistd.h>

    unsigned int alarm(unsigned int seconds);

        alarm()用来设置信号SIGALRM在经过参数seconds指定的秒数后传送给目前的进程。如果参数seconds 0,则之前设置的闹钟会被取消,并将剩下的时间返回。

    alarm示例

    View Code
    #include <unistd.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>

    void handler(int sig)
    {
    printf("hello\n");
    }

    int main()
    {
    int i;
    signal(SIGALRM, handler);
    alarm(5);
    for (i = 0; i < 7; i++)
    {
    printf("sleep %d ...\n", i);
    sleep(1);

    }
    return 0;
    }

    2)kill

    #include <sys/types.h>

    #include <signal.h>

    int kill(pid_t pid, int sig);

    The kill() system call can be used to send any signal to any process group or process.

        kill()用来送指定的信号sig给参数pid指定的进程。参数pid有几种情况:

    pid>0 将信号传给进程识别码为pid 的进程。

    pid=0 将信号传给和目前进程相同进程组的所有进程

    pid=-1 将信号广播传送给系统内所有的进程

    pid<0 将信号传给进程组识别码为pid绝对值的所有进程

    3)int pause(void);

        pause()会令目前的进程暂停(进入睡眠状态),直到被信号(signal)所中断。

    int raise(int sig);

    //The raise() function sends a signal to the current process. It is equivalent to kill(getpid(), sig);

    4)#include<signal.h>

    int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);

        sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILLSIGSTOP以外的所有信号。

    struct sigaction

    {

    void (*sa_handler) (int);

    sigset_t sa_mask;

    int sa_flags;

    void (*sa_restorer) (void);

    }

    sa_handler参数和signal()的参数handler相同,代表新的信号处理函数;

    sa_mask 用来设置在处理该信号时暂时将sa_mask指定的信号搁置。sa_mask gives a mask of signals which should be blocked during execution of the signal handler. In addition, the signal which triggered the handler will be blocked, unless the SA_NODEFER flag is used.

    sa_restorer 此参数没有使用。

    sa_flags 用来设置信号处理的其他相关操作。OR运算(|)组合:

    a. A_NOCLDSTOP : 如果参数signumSIGCHLD,则当子进程暂停时并不会通知父进程

    b. SA_ONESHOT/SA_RESETHAND:当调用信号处理函数前,将此信号处理方式改为缺省值;SA_RESETHAND是这个标记的正式的POSIX名字,为了软件的可移植性,一般不用SA_ONESHOT

    c. SA_RESTART:被信号中断的系统调用会自行重启

    d. SA_NOMASK/SA_NODEFER:在处理此信号未结束前不理会此信号的再次到来。SA_NODEFER是这个标记的正式的POSIX名字,为了软件的可移植性,一般不用SA_NOMASK)

        如果参数oldact不是NULL指针,则原来的信号处理方式会由此结构sigaction 返回。

    示例代码

    View Code
    #include <unistd.h>
    #include <signal.h>
    #include <iostream>
    #include <cstdio>

    using namespace std;

    void show_handler(int sig)
    {
    cout << "I got signal " << sig << endl;
    for (int i = 0; i < 5; i++)
    {
    cout << "i = " << i << endl;
    sleep(1);
    }
    }

    int main()
    {
    int i;
    struct sigaction act, oldact;
    act.sa_handler = show_handler;
    act.sa_flags = SA_RESETHAND | SA_NODEFER;
    sigaddset(&act.sa_mask, SIGQUIT); //屏蔽ctrl+\信号
    //sigaction(SIGUSR1, &act, &oldact);
    sigaction(SIGINT, &act, &oldact);
    while(1)
    {
    sleep(1);
    cout << "sleeping " << i << endl;
    i++;
    //kill(getpid(), SIGUSR1); //通过kill,向当前进程进行发送信号SIGUSR1
    }
    }


  • 相关阅读:
    java代码中存在的Big Endian 和 Little Endian
    通过hbase实现日志的转存(MR AnalyserLogDataRunner和AnalyserLogDataMapper)
    hbase使用MapReduce操作1(基本增删改查)
    配置好Nginx后,通过flume收集日志到hdfs(记得生成本地log时,不要生成一个文件,)
    数据库分页查询
    将博客搬至CSDN
    Dev Winform本地化
    C#,OleDbType,Access 对应数据类型
    C#字符串转义和反转义
    C# 正则表达式
  • 原文地址:https://www.cnblogs.com/mydomain/p/2184355.html
Copyright © 2020-2023  润新知