当前位置:早雪网网络学院编程文档C/C++ → Unix编程/应用问答中文版 ---3.-lelf、-lkvm、-lkstat相关问题

Unix编程/应用问答中文版 ---3.-lelf、-lkvm、-lkstat相关问题

减小字体 增大字体 作者:不详  来源:supcode.com收集整理  发布时间:2005-7-22 19:40:34
om> 

为什么要学习使用setitimer(2),因为alarm(3)属于被淘汰的定时器技术。 

A: 小四 <cloudsky@263.net> 

下面是个x86/FreeBSD 4.3-RELEASE下的例子 

-------------------------------------------------------------------------- 
/* 
* File     : timer_sample.c 
* Author   : Unknown (Don't ask me anything about this program) 
* Complie  : gcc -Wall -pipe -O3 -o timer_sample timer_sample.c 
* Platform : x86/FreeBSD 4.3-RELEASE 
* Date     : 2001-09-18 15:18 
*/ 

/************************************************************************ 
*                                                                      * 
*                               Head File                              * 
*                                                                      * 
************************************************************************/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/time.h> 
#include <signal.h> 

/************************************************************************ 
*                                                                      * 
*                               Macro                                  * 
*                                                                      * 
************************************************************************/ 

typedef void Sigfunc ( int );  /* for signal handlers */ 

/************************************************************************ 
*                                                                      * 
*                            Function Prototype                        * 
*                                                                      * 
************************************************************************/ 

static void      Atexit       ( void ( *func ) ( void ) ); 
static void      init_signal  ( void ); 
static void      init_timer   ( void ); 
static void      on_alarm     ( int signo ); 
static void      on_terminate ( int signo ); 
static int       Setitimer    ( int which, const struct itimerval *value, 
                                struct itimerval *ovalue ); 
       Sigfunc * signal       ( int signo, Sigfunc *func ); 
static Sigfunc * Signal       ( int signo, Sigfunc *func ); 
static void      terminate    ( void ); 

/************************************************************************ 
*                                                                      * 
*                            Static Global Var                         * 
*                                                                      * 
************************************************************************/ 

/************************************************************************/ 

static void Atexit ( void ( *func ) ( void ) ) 

    if ( atexit( func ) != 0 ) 
    { 
        perror( "atexit" ); 
        exit( EXIT_FAILURE ); 
    } 
    return; 
}  /* end of Atexit */ 

/* 
* 初始化信号句柄 
*/ 
static void init_signal ( void ) 

    int i; 

    Atexit( terminate ); 
    for ( i = 1; i < 9; i++ ) 
    { 
        Signal( i, on_terminate ); 
    } 
    Signal( SIGTERM, on_terminate ); 
    Signal( SIGALRM, on_alarm ); 
    return; 
}  /* end of init_signal */ 

static void init_timer ( void ) 

    struct itimerval value; 

    value.it_value.tv_sec  = 1; 
    value.it_value.tv_usec = 0; 
    value.it_interval      = value.it_value; 
    Setitimer( ITIMER_REAL, &value, NULL ); 
}  /* end of init_timer */ 

static void on_alarm ( int signo ) 

    static int count = 0; 

    /* 
     * 演示用,这很危险 
     */ 
    fprintf( stderr, "count = %u\n", count++ ); 
    return; 


static void on_terminate ( int signo ) 

    /* 
     * 这次我们使用atexit()函数 
     */ 
    exit( EXIT_SUCCESS ); 
}  /* end of on_terminate */ 

static int Setitimer ( int which, const struct itimerval *value, 
                       struct itimerval *ovalue ) 

    int ret; 

    if ( ( ret = setitimer( which, value, ovalue ) ) < 0 ) 
    { 
        perror( "setitimer" ); 
        exit( EXIT_FAILURE ); 
    } 
    return( ret ); 
}  /* end of Setitimer */ 

Sigfunc * signal ( int signo, Sigfunc *func ) 

    struct sigaction act, oact; 

    act.sa_handler = func; 
    sigemptyset( &act.sa_mask ); 
    act.sa_flags   = 0; 
    if ( signo == SIGALRM ) 
    { 
#ifdef  SA_INTERRUPT 
        act.sa_flags |= SA_INTERRUPT;  /* SunOS 4.x */ 
#endif 
    } 
    else 
    { 
#ifdef  SA_RESTART 
        act.sa_flags |= SA_RESTART;  /* SVR4, 44BSD */ 
#endif 
    } 
    if ( sigaction( signo, &act, &oact ) < 0 ) 
    { 
        return( SIG_ERR ); 
    } 
    return( oact.sa_handler ); 
}  /* end of signal */ 

static Sigfunc * Signal ( int signo, Sigfunc *func ) 

    Sigfunc *sigfunc; 

    if ( ( sigfunc = signal( signo, func ) ) == SIG_ERR ) 
    { 
        perror( "signal" ); 
        exit( EXIT_FAILURE ); 
    } 
    return( sigfunc ); 
}  /* end of Signal */ 

static void terminate ( void ) 

    fprintf( stderr, "\n" ); 
    return; 
}  /* end of terminate */ 

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

    init_signal(); 
    init_timer(); 
    while ( 1 ) 
    { 
        /* 
         * 形成阻塞,降低CPU占用率 
         */ 
        getchar(); 
    } 
    return( EXIT_SUCCESS ); 
}  /* end of main */ 

/************************************************************************/ 

-------------------------------------------------------------------------- 

D: scz <scz@nsfocus.com> 

讨论一个问题。getchar()的作用是降低CPU占用率,可用top命令查看。 

timer_sample.c中换用ITIMER_PROF/SIGPROF后,你会发现上述程序无输出,我据此 
认为getchar()形成的阻塞不计算在进程虚拟时钟中,也不认为系统正在为进程利益 
而运行。 

如果进一步将getchar()去掉,直接一个while()无限循环,即使换用 
ITIMER_PROF/SIGPROF,程序还是有输出。不过top命令查看的结果让你吐血,CPU几 
乎无空闲。 

D: scz <scz@nsfocus.com> 

setitimer( ITIMER_REAL, &value, NULL )导致分发SIGALRM信号,如果同时使用 
alarm(),势毕造成冲突。此外注意sleep()、pause()等函数带来的冲突。 

上一页  [1] [2] 

[数据载入中...] [返回上一页] [打 印]