您的位置:首页 > 运维架构 > Linux

Linux学习笔记之---时钟和信号

2015-03-10 19:46 323 查看
7:时钟和信号

    7.1     UNIX中存在三种格式的时间:

            1.系统时间: 1970,1,1到现在的秒数(time_t)

            2.高分辨率时间:精确到微妙的时间(timeval结构体)

            3.日历时间:“年,月,日,时,分,秒“类型(tm结构)

        

    7.2     系统时间

            #include <time.h>

            time_t time(time_t *tloc);

            double difftime(time_t time2, time_t time1);

            time获取当前时间(秒)difftime返回两个时间的差值

    7.3     本地时间

            #include <time.h>

            struct tm *localtime (const time_t *clock);

            time_t mktime (struct tm *timeptr);            

            localtime将系统时间变成本地时间,mktime相反

            tm结构体部分类容:

            

            int tm_sec         秒,0~61(允许闰秒)

            int tm_min         分,0~59

            int tm_hour        时,0~23

            int tm_mday        日,0~31

            int tm_mon         月,0~11

            int tm_year        年,从1900年开始(这样使用:tm_year+1900)

            int tm_wday        星期,从周日开始,0~6

            

    7.4     软硬件异常类信号

            一般在程序执行了某些严重不合法的动作时发出

            1.SIGABRT

            本信号在调用abort函数时发出,函数abort退出进程,与exit类似

            2.SIGBUS

            本信号在总线错误时发出

            3.SIGEMT

            本信号在仿真器自陷时发出,一般由于操作系统不能正确模拟软件指令而产生

            4.SIGFPE

            本信号在浮点运算异常时发出,如浮点溢出,除数为0等

            5.SIGILL

            本信号在进程执行了非法硬件指令时发出,如程序本身出现代码错误,

            试图执行数据段或堆栈溢出等

            6.SIGPWR

            本信号在缺少电力时发出

            7.SIGSEGV

            “段违例“信号,在进程访问无效或无权限内存地址时发出

            8.SIGSYS

            错误的系统调用,比如指示系统调用的参数类型错误等

            9.SIGTRAP

            本信号在执行了断点指令或其他陷阱指令时发出,主要供调式用

            10.SIGXCPU

            本信号在进程超过cpu资源限制时发出

            11.SIGXFSZ

            本信号在进程扩大文件过程中超过文件最大资源限制时发出

            

    7.4     终止进程类信号

            本类信号可以终止程序的运行,部分信号生成core文件      

            1.SIGHUP

            终端断开链接后,终止该终端上的所有前后台进程

            2.SIGINT

            本信号在用户键入中断命令(ctrl+c,delete)时发出,终止进程

            3.SIGKILL

            立即结束程序的运行,本信号不能被阻塞,处理和忽略,

            4.SIGQUIT

            本信号在用户键入退出命令(ctrl+\)时发出,用于通知前台进程组终止进程并创建core文件

            5.SIGTERM

            程序结束的普通信号,它可以被阻塞和处理,与强制性终止进程的SIGKILL相比,

            SIGTERM要求程序自己正常退出。

            

    7.5     进程挂起类信号

            本类信号导致进程进入休眠状态,一般应用于程序的调式和资源抢占中

            1.SIGCONT

            激活休眠的进程,如果程序不在休眠状态则忽略,不能被阻塞但可以捕获,

            用于完成进程状态变化时执行特定的工作,比如vi在收到时将刷新屏幕

            2.SIGSTOP

            挂起进程,本信号不能被阻塞,忽略或处理

            3.SIGTSTP

            交互式挂起进程运行,本信号可以被忽略或处理

            4.SIGTTIN

            本信号在后台进程读取终端数据时发出,终端的其他进程将被挂起

            5.SIGTTOU

            本信号在后台进程写入终端数据时发出,终端的其它进程将被挂起

            

    7.6     定时器类信号

            本类信号一般由函数alram和setitimer发出,用于指示定时器定时完毕

            1.SIGALRM

            本信号在alarm函数定义的定时器到期时发出

            2.SIGPROF

            类似于信号SIGALRM和信号SIGVTALRM,但本信号在进程占用的

            cpu时间和系统调用的时间到期时发出

            3.SIGVTALRM

            虚拟时钟信号,定时内容为进程占用的cpu时间,比如函数setitimer设置的

            定时器到期时或产生此信号

            

    7.7     其他信号

            包括预留信号,I/O信号等

            1.SIGCHLD或SIGCLD

            本信号在子进程结束时向父进程发出,如果父进程没有处理这个信号也没有等待(wait)

            子进程,子进程虽然终止,但会在内核进程表中占有表项,这时的子进程称为僵死进程

            2.SIGPIPE

            管道错误信号,常适用于进程间通信

            3.SIGPOLL或SIGIO

            本信号在流设备文件描述符准备就绪,可以开始执行I/O操作时发出

            4.SIGURG

            本信号在进程出现紧急数据或者socket中接收了外带数据时发出

            5.SIGUSR1和SIGUSR2

            预留给用户自定义

            6.SIGWINCH

            本信号在终端的窗口大小改变时发出

            

    7.8     函数signal更改信号的默认处理方式,函数kill或raise可以向进程发送信号

           

    7.9     信号的忽略与捕捉

            函数signal设置对信号的操作动作

            #include <signal.h>

            void (*signal (int sig, void (*f), (int))) (int);

            其中void (*f), (int))是函数指针作参数

            sig指定了要处理的信号

            f指明了进程接收到sig后的动作:

            SIG_DFL     恢复信号默认处理机制

            SIG_IGN     忽略信号处理

            函数地址     调用信号捕获函数执行处理

            调用成功返回f的值否则SIG_ERR

            

    7.10    信号的显示发送

            #include <sys/types.h>

            #include <signal.h>

            int kill (pid_t pid, int signo);

            int raise(int signo);

            kill发送信号signo到pid决定的特定进程中,pid的取值如下:

            >0      发送信号signo到进程pid中

            0       发送信号signo到与调用进程同组进程中

            -1      发送信号signo到实际用户id等于调用进程的有效用户id的进程中

            <-1     发送信号signo到进程组id等于pid绝对值的进程中

            调用成功返回0,否则-1;

            raise向调用进程自身发送信号signo,成功时返回0,否则-1;

            
    7.11    普通定时器设置

            #include <unistd.h>

            unsigned int alarm(unsigned int seconds);

            如果seconds==0则定时器被取消   

            alarm总能调用成功,返回上次定时器剩余的定时时间

            

            使用步骤:

            1.设置捕获定时信号

            signal(SIGALRM, timefunc)

            2.定时

            在代码处调用alarm

            3.编写timefunc

                      

    7.12    精确定时器设置

            alarm设置的定时器只能精确到秒,而以下函数理论上可以精确到微妙

            #include <sys/select.h>

            #include <sys/itimer.h>

            int getitimer(int which,struct itimerval *value);

            int setitimer(int which,const struct itimerval *value,

                          struct itimerval *ovalue);

            setitimer可以提供三种定时器,可自动重新定时;

            参数which与定时器类型:

            ITIMER_REAL     定时真实时间,与alarm相同                 SIGLARM

            ITIMER_VIRT     定时进程在用户态下的实际执行时间            SIGVTALRM

            ITIMER_PROF     定时进程在用户态和核心态下的实际执行时间     SIGPROF

            

            在一个UNIX进程中,不能同时使用alarm和ITIMER_REAL类定时器;

            itimerval结构体:

            struct itimerval

            {

                struct timeval it_interval;     下次定时取值

                struct timeval it_value;        本次定时取值

            }

            timeval结构体

            {

                long tv_sec;    秒

                long tv_usec;   微妙

            }

            setitimer成功返回0,否则-1;ovalue如果不为空,返回上次的定时器状态

            

    7.13    全局跳转

            #include <setjmp.h>       

            int setjmp (jmp_buf env);

            void longjmp(jmp_buf env, int val);

            setjmp存储当前的堆栈环境到env,成功调用返回0,函数longjmp回复

            env中的堆栈信息,使程序转移到env保存的位置处重新执行

            UNIX中使用全局跳转的步骤

            1.定义jmp_buf变量

            #include <setjmp.h>

            jmp_buf env;

            2.在需要程序重复执行的地方调用setjmp

            i = setjmp(env);

            3.在调用函数setjmp后增加判断代码,确认程序的执行次数,避免产生死循环

            如下语句实现程序回退一次后退出的功能:

            if(i != 0) exit(0);

            4.在程序开始回退的位置调用longjmp如:

            longjmp(env,1);

            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: