系统编程之信号篇

信号(一)

一、kill –l产看所有的信号名,man 7 signal查看信号名及解释,man signal查看signal函数

二、中断分类

q 硬件中断(外部中断)

         外部中断是指由外部设备通过硬件请求的方式产生的中断,也称为硬件中断

q 软件中断(内部中断)

         内部中断是由CPU运行程序错误或执行内部程序调用引起的一种中断,也称为软件中断。

三、信号

q 信号是UNIX系统响应某些状况而产生的事件,进程在接收到信号时会采取相应的行动。

q 信号是因为某些错误条件而产生的,比如内存段冲突、浮点处理器错误或者非法指令等

q 信号是在软件层次上对中断的一种模拟,所以通常把它称为是软中断

四、信号与中断

q 信号与中断的相似点:

q (1)采用了相同的异步通信方式;

q (2)当检测出有信号或中断请求时,都暂停正在执行的程序而转去执行相应的处理程序;

q (3)都在处理完毕后返回到原来的断点;

q (4)对信号或中断都可进行屏蔽。

q 信号与中断的区别:

q (1)中断有优先级,而信号没有优先级,所有的信号都是平等的;

q (2)信号处理程序是在用户态下运行的,而中断处理程序是在核心态下运行;

q (3)中断响应是及时的,而信号响应通常都有较大的时间延迟。

五、进程对信号的响应

q 忽略信号

         不采取任何操作、有两个信号不能被忽略:SIGKILLSIGSTOP

q 捕获并处理信号

         内核中断正在执行的代码,转去执行先前注册过的处

q 执行默认操作

         默认操作通常是终止进程,这取决于被发送的信号。

六、signal

typedef void (*__sighandler_t) (int);

#define SIG_ERR ((__sighandler_t) -1)

#define SIG_DFL ((__sighandler_t) 0)

#define SIG_IGN ((__sighandler_t) 1)

q 函数原型:

         __sighandler_t signal(int signum,__sighandler_t handler);

q 参数

signal是一个带signumhandler两个参数的函数,准备捕捉或屏蔽的信号由参数signum给出,接收到指定信号时将要调用的函数由handler给出

handler这个函数必须有一个int类型的参数(即接收到的信号代码),它本身的类型是void

handler也可以是下面两个特殊值:

                   SIG_IGN   屏蔽该信号

                   SIG_DFL   恢复默认行为

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int sig);

intmain(int argc, char *argv[])

{

         __sighandler_t oldhandler;

         oldhandler = signal(SIGINT, handler);

         if (oldhandler == SIG_ERR)

                   ERR_EXIT("signalerror");

 

         while (getchar() != '\n')

                   ;

         /*

         if (signal(SIGINT, oldhandler) ==SIG_ERR)

         */

         if (signal(SIGINT, SIG_DFL) == SIG_ERR)

                   ERR_EXIT("signalerror");

         for (;;) ;

         return 0;

}

 

voidhandler(int sig)

{

         printf("recv a sig=%d\n",sig);

}

 

信号(二)

一、信号的分类

可靠信号、不可靠信号、实时信号、非实时信号

二、信号发送

kill

raise

q 给自己发送信号。raise(sig)等价于kill(getpid(), sig);

killpg

q 给进程组发送信号。killpg(pgrp, sig)等价于kill(-pgrp, sig);

sigqueue

q 给进程发送信号,支持排队,可以附带信息。

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int sig);

intmain(int argc, char *argv[])

{

         if (signal(SIGUSR1, handler) ==SIG_ERR)

                   ERR_EXIT("signalerror");

         pid_t pid = fork();

         if (pid == -1)

                   ERR_EXIT("forkerror");

 

         if (pid == 0)

         {

                   kill(getppid(), SIGUSR1);

                   exit(EXIT_SUCCESS);

         }

 

         int n = 5;

         do

         {

                   n = sleep(n);

         } while (n > 0);

         return 0;

}

 

voidhandler(int sig)

{

         printf("recv a sig=%d\n",sig);

}

 

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int sig);

intmain(int argc, char *argv[])

{

         if (signal(SIGUSR1, handler) ==SIG_ERR)

                   ERR_EXIT("signalerror");

         pid_t pid = fork();

         if (pid == -1)

                   ERR_EXIT("forkerror");

 

         if (pid == 0)

         {

                   /*pid = getpgrp();

                   kill(-pid,SIGUSR1);*/

                   killpg(getpgrp(),SIGUSR1);

                   exit(EXIT_SUCCESS);

         }

 

         int n = 5;

         do

         {

                   n = sleep(n);

         } while (n > 0);

         return 0;

}

 

voidhandler(int sig)

{

         printf("recv a sig=%d\n",sig);

}

 

三、pause

q 将进程置为可中断睡眠状态。然后它调用schedule(),使linux进程调度器找到另一个进程来运行。

pause使调用者进程挂起,直到一个信号被捕获

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int sig);

intmain(int argc, char *argv[])

{

         if (signal(SIGINT, handler) == SIG_ERR)

                   ERR_EXIT("signalerror");

         for (;;)

         {

                   pause();

                   printf("pausereturn\n");

         }

         return 0;

}

 

voidhandler(int sig)

{

         printf("recv a sig=%d\n",sig);

         sleep(1);

}

 

信号(三)

一、alarm函数

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int sig);

intmain(int argc, char *argv[])

{

         if (signal(SIGALRM, handler) ==SIG_ERR)

                   ERR_EXIT("signal error");

 

         alarm(1);

         for (;;)

                   pause();

         return 0;

}

 

voidhandler(int sig)

{

         printf("recv a sig=%d\n",sig);

         alarm(1);

}

 

二、可重入函数

q 为了增强程序的稳定性,在信号处理函数中应使用可重入函数。

q 所谓可重入函数是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错。因为进程在收到信号后,就将跳转到信号处理函数去接着执行。如果信号处理函数中使用了不可重入函数,那么信号处理函数可能会修改原来进程中不应该被修改的数据,这样进程从信号处理函数中返回接着执行时,可能会出现不可预料的后果。不可再入函数在信号处理函数中被视为不安全函数。

q 满足下列条件的函数多数是不可再入的:(1)使用静态的数据结构,如getlogin()gmtime()getgrgid()getgrnam()getpwuid()以及getpwnam()等等;(2)函数实现时,调用了malloc()或者free()函数;(3)实现时使用了标准I/O函数的

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

 

typedefstruct

{

         int a;

         int b;

} TEST;

 

TESTg_data;

 

voidhandler(int sig);

intmain(int argc, char *argv[])

{

         TEST zeros = {0, 0};

         TEST ones = {1, 1};

         if (signal(SIGALRM, handler) ==SIG_ERR)

                   ERR_EXIT("signalerror");

 

         g_data = zeros;

         alarm(1);

         for (;;)

         {

                   g_data = zeros;

                   g_data = ones;

         }

         return 0;

}

 

voidunsafe_fun()

{

         printf("%d %d\n", g_data.a,g_data.b);

}

 

voidhandler(int sig)

{

         unsafe_fun();

         alarm(1);

}

信号(四)

一、信号在内核中的表示

二、信号集操作函数

#include<signal.h>

intsigemptyset(sigset_t *set);

intsigfillset(sigset_t *set);

intsigaddset(sigset_t *set, int signo);

intsigdelset(sigset_t *set, int signo);

intsigismember(const sigset_t *set, int signo);

三.sigprocmask函数

#include<signal.h>

intsigprocmask(int how, const sigset_t *set, sigset_t *oset);

q 功能:读取或更改进程的信号屏蔽字。

q 返回值:若成功则为0,若出错则为-1

q 如果oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改。如果osetset都是非空指针,则先将原来的信号屏蔽字备份到oset里,然后根据sethow参数更改信号屏蔽字。假设当前的信号屏蔽字为mask,下表说明了how参数的可选值。

#include <unistd.h>

#include <sys/stat.h>

#include <sys/wait.h>

#include <sys/types.h>

#include <fcntl.h>

 

#include <stdlib.h>

#include <stdio.h>

#include <errno.h>

#include <string.h>

#include <signal.h>

 

 

#define ERR_EXIT(m) \

do \

{ \

           perror(m);\

           exit(EXIT_FAILURE);\

}while(0)

 

void handler(int sig);

void printsigset(sigset_t *set)

{

int i;

for(i=1; i<NSIG; ++i)

{

           if(sigismember(set, i))

                    putchar('1');

           else

                    putchar('0');

}

printf("\n");

}

 

int main(int argc, char *argv[])

{

sigset_tpset;

sigset_tbset;

sigemptyset(&bset);

sigaddset(&bset,SIGINT);

if(signal(SIGINT, handler) == SIG_ERR)

           ERR_EXIT("signalerror");

if(signal(SIGQUIT, handler) == SIG_ERR)

           ERR_EXIT("signalerror");

 

sigprocmask(SIG_BLOCK,&bset, NULL);

for(;;)

{

           sigpending(&pset);

           printsigset(&pset);

           sleep(1);

}

return0;

}

 

void handler(int sig)

{

if (sig== SIGINT)

           printf("recva sig=%d\n", sig);

else if(sig == SIGQUIT)

{

           sigset_tuset;

           sigemptyset(&uset);

           sigaddset(&uset,SIGINT);

           sigprocmask(SIG_UNBLOCK,&uset, NULL);

}

}

信号(五)

一、sigaction

 

q 包含头文件<signal.h>

q 功能:sigaction函数用于改变进程接收到特定信号后的行为。

q 原型:

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

q 参数

q 该函数的第一个参数为信号的值,可以为除SIGKILLSIGSTOP外的任何一个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)

q 第二个参数是指向结构sigaction的一个实例的指针,在结构 sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理

q 第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldactNULL

q 返回值:函数成功返回0,失败返回-1

q 第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中应屏蔽掉哪些函数等等

structsigaction {

         void (*sa_handler)(int);

         void (*sa_sigaction)(int, siginfo_t *,void *);

         sigset_t sa_mask;

         int sa_flags;

         void (*sa_restorer)(void);

};

 

 

 

 

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int sig);

__sighandler_tmy_signal(int sig, __sighandler_t handler);

 

intmain(int argc, char *argv[])

{

/*

         struct sigaction act;

         act.sa_handler = handler;

         sigemptyset(&act.sa_mask);

         act.sa_flags = 0;

 

         if (sigaction(SIGINT, &act, NULL)< 0)

                   ERR_EXIT("sigactionerror\n");

*/

         my_signal(SIGINT, handler);

         for (;;)

                   pause();

         return 0;

}

 

__sighandler_tmy_signal(int sig, __sighandler_t handler)

{

         struct sigaction act;

         struct sigaction oldact;

         act.sa_handler = handler;

         sigemptyset(&act.sa_mask);

         act.sa_flags = 0;

 

         if (sigaction(sig, &act,&oldact) < 0)

                   return SIG_ERR;

 

         return oldact.sa_handler;

}

 

voidhandler(int sig)

{

         printf("recv a sig=%d\n",sig);

}

 

 

 

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int sig);

 

intmain(int argc, char *argv[])

{

         struct sigaction act;

         act.sa_handler = handler;

         sigemptyset(&act.sa_mask);

         sigaddset(&act.sa_mask, SIGQUIT);

         act.sa_flags = 0;

 

         if (sigaction(SIGINT, &act, NULL)< 0)

                   ERR_EXIT("sigactionerror");

 

         for (;;)

                   pause();

         return 0;

}

 

voidhandler(int sig)

{

         printf("recv a sig=%d\n",sig);

         sleep(5);

}

信号(六)

 

//01sigaction.c

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int sig);

 

intmain(int argc, char *argv[])

{

         struct sigaction act;

         act.sa_handler = handler;

         sigemptyset(&act.sa_mask);

         act.sa_flags = 0;

 

         sigset_ts;

         sigemptyset(&s);

         sigaddset(&s,SIGINT);

         sigprocmask(SIG_BLOCK,&s, NULL);

 

         if (sigaction(SIGINT, &act, NULL)< 0)

                   ERR_EXIT("sigactionerror");

 

         for (;;)

                   pause();

         return 0;

}

 

voidhandler(int sig)

{

         printf("recv a sig=%d\n",sig);

         sleep(5);

}

 

 

//02sigaction_rev.c

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int, siginfo_t *, void *);

 

intmain(int argc, char *argv[])

{

         struct sigaction act;

         act.sa_sigaction = handler;

         sigemptyset(&act.sa_mask);

         act.sa_flags = SA_SIGINFO;

 

         if (sigaction(SIGINT, &act, NULL)< 0)

                   ERR_EXIT("sigactionerror");

 

         for (;;)

                   pause();

         return 0;

}

 

voidhandler(int sig, siginfo_t *info, void *ctx)

{

         printf("recv a sig=%d data=%ddata=%d\n", sig, info->si_value.sival_int, info->si_int);

}

 

//03sigqueue

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(int argc, char *argv[])

{

         if (argc != 2)

         {

                   fprintf(stderr, "Usage%s pid\n", argv[0]);

                   exit(EXIT_FAILURE);

         }

 

         pid_t pid = atoi(argv[1]);

         union sigval v;

         v.sival_int = 100;

         sigqueue(pid, SIGINT, v);

         return 0;

}

 

一、sigqueue函数

q 功能:新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用。

q 原型:

         int sigqueue(pid_t pid, int sig, constunion sigval value);

q 参数

 sigqueue的第一个参数是指定接收信号的进程id,第二个参数确定即将发送的信号,第三个参数是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。

q 返回值成功返回0,失败返回-1

sigqueue()kill()传递了更多的附加信息,但sigqueue()只能向一个进程发送信号,而不能发送信号给一个进程组。

typedef union sigval

 {

intsival_int;

void*sival_ptr;

}sigval_t;

 

//04sigaciton_rev.c

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int);

 

intmain(int argc, char *argv[])

{

         struct sigaction act;

         act.sa_handler = handler;

         sigemptyset(&act.sa_mask);

         act.sa_flags = 0;

 

         sigset_t s;

         sigemptyset(&s);

         sigaddset(&s, SIGINT);

         sigaddset(&s, SIGRTMIN);

         sigprocmask(SIG_BLOCK, &s, NULL);

         if (sigaction(SIGINT, &act, NULL)< 0)

                   ERR_EXIT("sigactionerror");

 

         if (sigaction(SIGRTMIN, &act, NULL)< 0)

                   ERR_EXIT("sigactionerror");

 

         if (sigaction(SIGUSR1, &act, NULL)< 0)

                   ERR_EXIT("sigactionerror");

         for (;;)

                   pause();

         return 0;

}

 

voidhandler(int sig)

{

         if (sig == SIGINT || sig == SIGRTMIN)

                   printf("recv asig=%d\n", sig);

         else if (sig == SIGUSR1)

         {

                   sigset_t s;

                   sigemptyset(&s);

                   sigaddset(&s, SIGINT);

                   sigaddset(&s, SIGRTMIN);

                   sigprocmask(SIG_UNBLOCK,&s, NULL);

         }

}

 

//05sigqueue_send.c

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(int argc, char *argv[])

{

         if (argc != 2)

         {

                   fprintf(stderr, "Usage%s pid\n", argv[0]);

                   exit(EXIT_FAILURE);

         }

 

         pid_t pid = atoi(argv[1]);

         union sigval v;

         v.sival_int = 100;

         sigqueue(pid, SIGINT, v);

         sigqueue(pid, SIGINT, v);

         sigqueue(pid, SIGINT, v);

         sigqueue(pid, SIGRTMIN, v);

         sigqueue(pid, SIGRTMIN, v);

         sigqueue(pid, SIGRTMIN, v);

         sleep(3);

         kill(pid, SIGUSR1);

         return 0;

}

 

信号(七)

一、三种不同精度的睡眠

unsignedint sleep(unsigned int seconds);

intusleep(useconds_t usec);

intnanosleep(const struct timespec *req, struct timespec *rem);

 

二、setitimer

q 包含头文件<sys/time.h>

q 功能setitimer()alarm功能强大,支持3种类型的定时器

q 原型:

intsetitimer(int which, const struct itimerval *value, struct itimerval *ovalue));

q 参数

q 第一个参数which指定定时器类型

q 第二个参数是结构itimerval的一个实例,结构itimerval形式

q 第三个参数可不做处理。

q 返回值:成功返回0失败返回-1

 

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

#include<sys/time.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidhandler(int sig)

{

         printf("recv a sig=%d\n",sig);

}

 

intmain(int argc, char *argv[])

{

         if (signal(SIGALRM, handler) ==SIG_ERR)

                   ERR_EXIT("signalerror");

 

         struct timeval tv_interval = {1, 0};

         struct timeval tv_value = {5, 0};

         struct itimerval it;

         it.it_interval = tv_interval;

         it.it_value = tv_value;

         setitimer(ITIMER_REAL, &it, NULL);

 

         for (;;)

                   pause();

         return 0;

}

ITIMER_REAL:经过指定的时间后,内核将发送SIGALRM信号给本进程

ITIMER_VIRTUAL:程序在用户空间执行指定的时间后,内核将发送SIGVTALRM信号给本进程

ITIMER_PROF:进程在内核空间中执行时,时间计数会减少,通常与ITIMER_VIRTUAL共用,代表进程在用户空间与内核空间中运行指定时间后,内核将发送SIGPROF信号给本进程。

 

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

#include<sys/time.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

 

intmain(int argc, char *argv[])

{

         struct timeval tv_interval = {1, 0};

         struct timeval tv_value = {1, 0};

         struct itimerval it;

         it.it_interval = tv_interval;

         it.it_value = tv_value;

         setitimer(ITIMER_REAL, &it, NULL);

 

         int i;

         for (i=0; i<10000; i++);

                   ;

 

         struct itimerval oit;

         setitimer(ITIMER_REAL, &it,&oit);

         printf("%d %d %d %d\n",(int)oit.it_interval.tv_sec, (int)oit.it_interval.tv_usec,(int)oit.it_value.tv_sec, (int)oit.it_value.tv_usec);

 

         return 0;

}

 

 

#include<unistd.h>

#include<sys/stat.h>

#include<sys/wait.h>

#include<sys/types.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<signal.h>

#include<sys/time.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

 

intmain(int argc, char *argv[])

{

         struct timeval tv_interval = {1, 0};

         struct timeval tv_value = {1, 0};

         struct itimerval it;

         it.it_interval = tv_interval;

         it.it_value = tv_value;

         setitimer(ITIMER_REAL, &it, NULL);

 

         int i;

         for (i=0; i<10000; i++);

                   ;

 

         getitimer(ITIMER_REAL, &it);

         printf("%d %d %d %d\n",(int)it.it_interval.tv_sec, (int)it.it_interval.tv_usec,(int)it.it_value.tv_sec, (int)it.it_value.tv_usec);

 

         return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值