zoukankan      html  css  js  c++  java
  • 【linux高级程序设计】(第十章)Linux异步信号处理机制

    发送信号

    在终端用kill命令杀死当前终端

    r

    如上, 使用 kill -SIGCONT 2563 时,终端忽略了该信号

             使用 kill -SIGABRT 2563 时,终端退出。需要重新输入用户名密码登陆。

    int kill (__pid_t __pid, int __sig) :向指定进程发送信号。第一个参数为要传递信号的进程号,第二个参数为发送的信号值。

    int raise (int __sig) :给当前进程发一个信号,即唤醒一个进程.成功返回0,否则返回-1.

      等价于

    if(kill(getpid(), int __sig) == -1)
        perror("raise");

      使用raise函数

    if(raise(SIGUSR1)!= 0)
        perror("Failed to raise SIGUSR1");

    unsigned int alarm (unsigned int __seconds) :在指定时间内产生SIGALRM信号给当前进程。此函数每调用一次,产生一个信号,并不是循环产生信号的。默认接收到该信号后进程终止执行。

    #include<signal.h>
    #include<stdio.h>
    int main(void)
    {
        printf("first time return: %d
    ", alarm(4)); //4秒后生成ALARM信号
        sleep(1);
        printf("after sleep(1), remain: %d
    ", alarm(2));
        printf("renew alarm, remain:%d
    ", alarm(1));
    }

    __useconds_t ualarm (__useconds_t __value, __useconds_t __interval) :在第一个参数(单位:us)内产生SIGALRM信号,然后每个指定时间(第二个参数,为us为单位)重复产生SIGALRM信号。执行成功,返回0.

    #include<unistd.h>
    #include<signal.h>
    #include<errno.h>
    #include<stdio.h>
    void handler()
    {
        printf("int:hello
    ");
    }
    int main()
    {
        int i;
        signal(SIGALRM, handler);
        printf("%d
    ", ualarm(50, 20));  //会发送多次信号 如果是alarm只发送一次信号
        while(1)
        {
            sleep(1);
            printf("test
    ");
        }
    }

    int usleep (__useconds_t __useconds):sleep函数的高精度版本

    shell 命令 time 可以计算某个进程运行时间。

    time cat test.txt

    real : 从执行到结束的时间

    user : 进程用户空间运行时间

    sys : 进程在内核中运行时间

    int getitimer(int which, struct itimerval * value):获取定时器的相关信息

    int setitimer(int which, const struct inimerval *value, struct itimerval *ovalue):设置定时器的相关信息

    第一个参数:选择哪个定时器,有三个定时器可选

    • ITIMER_REAL: 以逝去时间递减,时钟到来后产生SIGALRM信号
    • ITIMER_VIRTUAL: 当进程执行自身代码时递减,时钟超时产生SIGVTALRM信号
    • ITIMER_PROF: 当进程自身执行或者是系统在执行进程的系统调用时递减,时钟超时产生SIGPROF信号。可联合ITIMER_VIRTUAL计算进程在用户空间和系统空间的运行时间。

    第二个参数类型声明如下:

    struct itimerval{
        struct timeval it_interval;  //间隔值
        struct timeval it_value; //当前剩余值
    };
    struct timeval{
        long tv_sec;  //s为单位
        long tv_usec; //ms为单位
    };

    例子:

    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/time.h>
    #include<signal.h>
    
    int main(void)
    {
        struct itimerval setvalue;
        setvalue.it_interval.tv_sec = 3;
        setvalue.it_interval.tv_usec = 0;
        setvalue.it_value.tv_sec = 3;
        setvalue.it_value.tv_usec = 0;
        setitimer(ITIMER_REAL, &setvalue, NULL);
        
        setitimer(ITIMER_VIRTUAL, &setvalue, NULL);
        
        setvalue.it_value.tv_sec = 1;
        setitimer(ITIMER_PROF, &setvalue, NULL);
        
        while(1)
        {
            struct itimerval value;
            getitimer(ITIMER_REAL, &value);
            printf("ITIMER_REAL: internal:%ds%dms, remain:%ds%dms
    ",
                value.it_interval.tv_sec, value.it_interval.tv_usec,
                value.it_value.tv_sec, value.it_value.tv_usec);
            getitimer(ITIMER_VIRTUAL, &value);
            printf("ITIMER_VIRTUAL: internal:%ds%dms, remain:%ds%dms
    ",
                value.it_interval.tv_sec, value.it_interval.tv_usec,
                value.it_value.tv_sec, value.it_value.tv_usec);
            getitimer(ITIMER_PROF, &value);
            printf("ITIMER_PROF: internal:%ds%dms, remain:%ds%dms
    ",
                value.it_interval.tv_sec, value.it_interval.tv_usec,
                value.it_value.tv_sec, value.it_value.tv_usec);
            
            sleep(1);
        }
    }

    ??为什么第二次和第三次的ITIMER_VIRTUAL的剩余值有4187ms??比间隔值还大?

    ??为什么我设定的值是3s0ms但是会显示3s187ms??

  • 相关阅读:
    Docker容器启动时初始化Mysql数据库
    使用Buildpacks高效构建Docker镜像
    Mybatis 强大的结果集映射器resultMap
    Java 集合排序策略接口 Comparator
    Spring MVC 函数式编程进阶
    换一种方式编写 Spring MVC 接口
    【asp.net core 系列】6 实战之 一个项目的完整结构
    【asp.net core 系列】5 布局页和静态资源
    【asp.net core 系列】4. 更高更强的路由
    【Java Spring Cloud 实战之路】- 使用Nacos和网关中心的创建
  • 原文地址:https://www.cnblogs.com/dplearning/p/4681414.html
Copyright © 2011-2022 走看看