如何使安全使用信号

”如何使用setitimer来定时“  这片文章讲解了如何使用timer来完成定时工作,但是它使用了一个休眠函数,对于信号的处理实时性不好,这里有了一套改进的方法,以供网友讨论。
#include <iostream>
#include <sys/time.h>
#include <signal.h>
#include <assert.h>

using namespace std;

class SignalUtil
{
    void (*sigHandler)( int signum );
    int signum;
    struct sigaction oact;

    void installSignal()
    {
        struct sigaction cact;
       
        // Initialize current structure of signal action
        sigemptyset( &cact.sa_mask );
        cact.sa_flags     = 0;
        cact.sa_handler = sigHandler;
       
        // Install signal hander
        int res = sigaction( signum, &cact, &oact );
        assert( res == 0 );
    }
   
    void uninstallSignal()
    {
        // Restore signal action
        int res = sigaction( signum, &oact, NULL );
        assert( res == 0 );
    }   
   
public:
    SignalUtil( void (*_sigHandler)( int signum ), int _signum )
    : sigHandler( _sigHandler ), signum( _signum )
    {
        cout << "SinUtil constructor" << endl;
        installSignal();
    }

    virtual ~SignalUtil()
    {
        cout << "SinUtil destructor" << endl;
        uninstallSignal();
    }
   
    // When receiving signal, it will return. Otherwise blocking it forever
    virtual void waitSignal()
    {
        sigset_t cset;
        sigset_t oset;
        sigset_t wset;
       
        // Initialize waiting signal set
        int res = sigemptyset( &wset );
        assert( res == 0 );
       
        // Acquire current signal set
        res = sigprocmask( 0, NULL, &cset );
        assert( res == 0 );
       
        // Mark flags to block signal
        res = sigaddset( &cset, signum );
        assert( res == 0 );
       
        // Block signal
        res = sigprocmask( SIG_BLOCK, &cset, &oset );
        assert( res == 0 );
       
        // Wait signal
        res = sigsuspend( &wset );
        assert( res == -1 && errno == EINTR );
           
        // Restore signal
        res = sigprocmask( SIG_BLOCK, &oset, NULL );
        assert( res == 0 );
    }
};

volatile static long counter = 0;

static void notify( int signum )
{
    assert( signum == SIGALRM );
    cout << "Notify" << endl;
    ++ counter;
}

static void installTimer( void )
{
    struct itimerval  tim_ticks;

    tim_ticks.it_value.tv_sec      = 0;
    tim_ticks.it_value.tv_usec     = 10;
    tim_ticks.it_interval.tv_sec   = 0;
    tim_ticks.it_interval.tv_usec  = 10;

    int res = setitimer( ITIMER_REAL, &tim_ticks, 0 );
    assert( res == 0 );
}

int main( void )
{
     SignalUtil sigUtil( notify, SIGALRM );
    
     installTimer();
         
    for ( ; ; )
    {
        sigUtil.waitSignal();
        cout << "counter = " << counter << endl;
    }
  
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值